第5章 PIC16F877的外围功能模块
5.1.2 简单应用实例
该例用于令与PORTD口相连的8个发光二极管前4个点亮,后4个熄灭。在调试程序前,应使与PORTD口相连的8位拔码开关拔向相应的位置。
例5.1 PORTD输出
#include
main()
{
TRISD=0X00; /*TRISD寄存器被赋值,PORTD每一位都为输出*/
while(1); /*循环执行点亮发光二极管的语句*/
{
PORTD=0XF0; /*向PORTD送数据,点亮LED(由实验模板*/
/*的设计决定相应位置低时LED点亮)。*/
}
}
5.2.1 MSSP模块SPI方式功能简介
下面是一段简单的SPI初始化例程,用于利用SPI工作方式输出数据的场合。
例5.2 SPI初始化程序
/*spi初始化子程序*/
void SPIINIT()
{
PIR1=0; /*清除SPI中断标志*/
SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */
SSPSTAT=0xC0;
TRISC=0x00; /*SDO引脚为输出,SCK引脚为输出*/
}
5.2.3 程序清单
下面给出已经在实验板上调试通过的一个程序,可作为用户编制其它程序的参考。
#include
/*该程序用于在8个LED上依次显示1~8等8个字符*/
static volatile int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
volatile unsigned char data;
#define PORTAIT(adr,bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/
static bit PORTA_5 @ PORTAIT(PORTA,5);
/*spi初始化子程序*/
void SPIINIT()
{
PIR1=0;
SSPCON=0x30; /* SSPEN=1;CKP=0 , FOSC/4 */
SSPSTAT=0xC0;
TRISC=0x00; /*SDO引脚为输出,SCK引脚为输出*/
}
/*系统各输入输出口初始化子程序*/
void initial()
{
TRISA=0x00; /*A口设置为输出*/
INTCON=0x00; /*关闭所有中断*/
PORTA_5=0; /*LACK送低电平,为锁存做准备*/
}
/*SPI发送子程序*/
void SPILED(int data)
{
SSPBUF=data; /*启动发送*/
do
{
;
}while(SSPIF==0); /*等待发送完毕*/
SSPIF=0; /*清除SSPIF标志*/
}
/*主程序*/
main()
{
unsigned I;
initial(); /*系统初始化*/
SPIINIT() ; /*SPI初始化*/
for(i=8;i>0;i--) /*连续发送8个数据*/
{
data=table[i]; /*通过数组的转换获得待显示的段码*/
SPILED(data); /*发送显示段码显示*/
}
PORTA_5=1; /*最后给锁存信号,代表显示任务完成*/
}
5.3.3 程序清单
下面给出已经在实验板上调试通过的程序,可作为用户编制其它程序的参考。有关显示部分的SPI初始化,请读者参考5.2节。
#include
/*该程序用于按下相应的键时,在第一个8段LED上显示相应的1~4的字符*/
#define PORTAIT(adr,bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/
static bit PORTA_5 @ PORTAIT(PORTA,5);
#define PORTBIT(adr, bit) ((unsigned)(&adr)*8+(bit)) /*绝对寻址位操作指令*/
static bit PORTB_5 @ PORTBIT(PORTB,5);
static bit PORTB_4 @ PORTBIT(PORTB,4);
static bit PORTB_1 @ PORTBIT(PORTB,1) ;
static bit PORTB_2 @ PORTBIT(PORTB,2) ;
unsigned int I;
unsigned char j;
int data;
/*spi初始化子程序*/
void SPIINIT()
{
PIR1=0;
SSPCON=0x30;
SSPSTAT=0xC0;
TRISC=0xD7; /*SDO引脚为输出,SCK引脚为输出*/
}
/*系统各输入输出口初始化子程序*/
void initial()
{
TRISA=0xDF;
TRISB=0XF0; /*设置与键盘有关的各口的数据方向*/
INTCON=0x00; /*关闭所有中断*/
data=0X00; /*待显示的寄存器赋初值*/
PORTB=0X00; /*RB1 RB2 先送低电平*/
j=0;
}
/*软件延时子程序*/
void DELAY()
{
for(i = 6553; --i ;)
continue;
}
/*键扫描子程序*/
int KEYSCAN()
{
while(1)
{
if ((PORTB_5==0)||(PORTB_4==0))
break;
} /*等待有键按下*/
DELAY(); /*软件延时*/
if ((PORTB_5==0)||(PORTB_4==0))
KEYSERVE(); /*如果仍有键按下,则调用键服务子程序*/
else j=0x00; /*如果为干扰,则令返回值为0*/
return(j);
}
/*键服务子程序*/
int KEYSERVE()
{
PORTB=0XFD ;
if(PORTB_5==0) j=0X01;
if(PORTB_4==0) j=0X03;
PORTB=0XFB;
if(PORTB_5==0) j=0X02;
if(PORTB_4==0) j=0X04;/*以上根据按下的键确定相应的键值*/
PORTB=0X00; /*恢复PORTB的值*/
while(1)
{
if((PORTB_5==1)&&(PORTB_4==1)) break;/*等待键盘松开*/
}
return(j);
}
/*SPI发送子程序*/
void SPILED(int data)
{
SSPBUF=data; /*启动发送*/
do
{
;
}while(SSPIF==0); /*等待发送完毕
SSPIF=0;
}
/*主程序*/
main()
{
static int table[20]={0xc0,0xf9,0xa4,0xb0,0x99,0x92,0x82,0XD8,0x80,0x90,0x88,0x83,0xc6,0xa1,0x86,0x8e,0x7f,0xbf,0x89,0xff};
initial();/*系统初始化*/
SPIINIT() ;/*SPI初始化*/
while(1)
{
刚接触pic单片机 使用的是MPLAB IDE 对于配置字的要求可以通过软件进行设置
也可以用__CONFIG();进行设置
但是发现官网上用的是MOLAB X IDE 对于配置字的格式要求
变成了#pragma 当然也可以通过软件的窗口>>pic存储器视图>>配置字
对配置字进行设置
XC8对于中断的格式也有了变化 __interrupt(优先级)
#pragma config FOSC = INTRC_CLKOUT// Oscillator Selection bits (INTOSC oscillator: CLKOUT function on RA6/OSC2/CLKOUT pin, I/O function on RA7/OSC1/CLKIN)
#pragma config WDTE = OFF // Watchdog Timer Enable bit (WDT disabled and can be enabled by SWDTEN bit of the WDTCON register)
#pragma config PWRTE = OFF // Power-up Timer Enable bit (PWRT disabled)
#pragma config MCLRE = ON // RE3/MCLR pin function select bit (RE3/MCLR pin function is MCLR)
#pragma config CP = OFF // Code Protection bit (Program memory code protection is disabled)
#pragma config CPD = OFF // Data Code Protection bit (Data memory code protection is disabled)
#pragma config BOREN = ON // Brown Out Reset Selection bits (BOR enabled)
#pragma config IESO = OFF // Internal External Switchover bit (Internal/External Switchover mode is disabled)
#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enabled bit (Fail-Safe Clock Monitor is disabled)
#pragma config LVP = OFF // Low Voltage Programming Enable bit (RB3 pin has digital I/O, HV on MCLR must be used for programming)
// CONFIG2
#pragma config BOR4V = BOR40V // Brown-out Reset Selection bit (Brown-out Reset set to 4.0V)
#pragma config WRT = OFF // Flash Program Memory Self Write Enable bits (Write protection off)
// #pragma config statements should precede project file includes.
// Use project enums instead of #define for ON and OFF.
//=======================================用户配置区,供用户修改===========================================
#define TIME2 1000 //长按键时间设置,单位ms ,1000 = 1s 范围:1~10s
//=========================================================================================================
// 以下为代码区,请勿改动! *
// 以下为代码区,请勿改动! *
// 以下为代码区,请勿改动! *
// 以下为代码区,请勿改动! *
// 以下为代码区,请勿改动! *
// 以下为代码区,请勿改动! *
// 以下为代码区,请勿改动! *
//=============================================硬件连接示意===============================================
//
// ___短 _ 长 _______
// |_| |_________| PIC10F200/202
// +---------+
// KEY 长/短按键 ---|GP0 GP3|---
// | |
// |GND VDD|
// | | __ ___
// 长按键翻转输出 ---|GP1 GP2|---短按键翻转输出 _| |____| |____
// +---------+
// __________ _____________
// _| |___________| |____
//
//--------------------------------------------------------------------------------------------------------
/*
长/短按键IO口电平翻转程序
说明:1.该程序通过检测GP0管脚的有效按键长短,循环翻转GP2和GP1管脚的输出电平高低。
每检测到一个短按键,则对GP2管脚输出电平进行一次翻转,每检测到一个长按键,
则对GP1管脚输出电平进行一次翻转。
2.按键是带有状态机的键盘扫描程序,可有效对按键消抖,抗干扰能力极强。
3.长按键的时间可通过程序顶端的参数进行方便的设置,以满足现场需求。
4.GP1、GP2在单片机默认状态和复位后输出电平为低。
5.待机功耗为400uA(@5V),长按键功耗为500uA(@5V)。
6.已启用内部弱上拉,按键可以不加上拉电阻,如果要保证信号可靠,可以加上拉电阻,
建议选择>=100K的电阻,以降低长时间按下按键在电阻上的功耗。
日期:2014/09/04 版本:V2.0
*/
//=========================================================================================================
#include
#define Key_Read_T 25 //等间隔读取键值,单位ms
#define KEY_IO GP0 //按键信号输入
#define Short_Out GP1 //短按按键响应数出口
bit short_out; //记录Short_Out当前状态
bit short_IF; //短按响应标志
#define Long_Out GP2 //长按按键响应数出口
bit long_out; //记录Long_Out当前状态
bit long_IF; //长按响应标志
unsigned char KEY_State=0; /*按键的状态变量*/
#define NOKEY 0
#define PUSH_KEY 1
#define LONG_PUSH 2
#define INITIAL_25MS 161 //相对于本系统与定时器时钟,本数据为固定值。定时器增计数,计数周期为256us,计97个数约为25mS。256-97+2=161
/
* 名 称:Key_ScanIO()
* 功 能:扫描键盘IO口并判断按键事件
* 入口参数:Ticklong:长按键有效时长,单位ms
* 出口参数:无
* 说 明: 该函数需要每隔25(Key_Read_T)ms,调用一次。最好放在定时中断内执行。
如果中断间隔太长,可能丢键;间隔太短不能消除抖动。
/
void Key_ScanIO(int Ticklong)
{
static unsigned int KeyTimerS;
//===============================按键========================================
if(KEY_State==PUSH_KEY) KeyTimerS++; /*定时器,时间间隔25ms*/
else KeyTimerS=0;
switch(KEY_State) //根据按键的状态决定程序分支
{
case NOKEY: //------------------在未按键状态下--------------------------
{ //若键被按下,按键状态变为"短按状态"。
if(KEY_IO==0) KEY_State=PUSH_KEY;
break;
}
case PUSH_KEY: //-------------按键处于"短按状态"时------------------------
{
if(KEY_IO!=0) //若键被释放,认为是一次短按键
{
KEY_State=NOKEY; //并回到"未按下状态"
short_IF = 0;
long_IF = 0;
}
else if(KeyTimerS>Ticklong) //若按键时间超过Ticks毫秒,认为是一次长按键,
{
KEY_State=LONG_PUSH; // 按键状态变为"长按状态"
}
break;
}
case LONG_PUSH: //------------按键处于"长按状态"时--------------------
{
if(KEY_IO!=0) //若键被释放,回到未按键状态
{
KEY_State=NOKEY;
short_IF = 0;
long_IF = 0;
}
break;
}
}
}
/
* 名 称:Key_Answer()
* 功 能:根据按键状态作出响应,控制IO管脚输出电平翻转
* 入口参数:Ticklong:长按键有效时长,单位ms
* 出口参数:无
/
void Key_Answer(void)
{
if((KEY_State==PUSH_KEY)&&(short_IF == 0))
{
short_out = ~short_out;
Short_Out = short_out;
short_IF = 1;
}
if((KEY_State==LONG_PUSH)&&(long_IF == 0))
{
long_out = ~long_out;
Long_Out = long_out;
long_IF = 1;
}
}
/
名 称:main()
功 能:主程序
入口参数:无
出口参数:无
*/
void main()
{
//设置时钟周期Fosc = 4MHz,系统时钟,无法设置
OPTION = 0x97; //复位值0xFF。TIMER0的时钟源是Fosc/4,1us。TIMER0 256预分频,256us
// CMCON0 = 0xE1;
TRISGPIO = 0x09; //GP1、GP2配置为输出。0为输出,1为输入
short_out = 0;
Short_Out = short_out;
long_out = 0;
Long_Out = long_out; //为输出赋初值
TMR0 = INITIAL_25MS; //增计数,计数周期为256us,计97个数约为25mS。256-125+2=97
while(1)
{
#asm
CLRWDT
#endasm
程序代码:
#include
#define uchar unsigned char
#define uint unsigned int
__CONFIG(HS&WDTDIS);
#include "Drive_Serial.h"
uchar line1_data[] = {"顶顶电子欢迎您!"};
uchar line2_data[] = {" www*ddmcu*com "};
uchar line3_data[] = {"DD-900实验开发板"};
uchar line4_data[] = {"TEL: "};
/端口设置函数/
void port_init(void)
{
TRISC = 0x00;
TRISD = 0x00;
}
/以下是闪烁三次函数/
void lcd_flash()
{
Delay_ms(1000); //控制停留时间
lcd_wcmd(0x08); //关闭显示
Delay_ms(500); //延时0.5s
lcd_wcmd(0x0c); //开显示
Delay_ms(500); //延时0.5s
lcd_wcmd(0x08); //关闭显示
Delay_ms(500); //延时0.5s
lcd_wcmd(0x0c); //开显示
Delay_ms(500); //延时0.5s
lcd_wcmd(0x08); //关闭显示
Delay_ms(500); //延时0.5s
lcd_wcmd(0x0c); //开显示
Delay_ms(500); //延时0.5s
}
/以下是主函数/
void main()
{
uchar i;
port_init();
Delay_ms(100); //上电,等待稳定
lcd_init(); //初始化LCD
while(1)
{
LocateXY(0,0); //设置显示位置为第0行,0列
for(i=0;i<16;i++)
{
lcd_wdat(line1_data[i]);
Delay_ms(100); //每个字符停留的时间为100ms
}
LocateXY(0,1); //设置显示位置为第1行第0列
for(i=0;i<16;i++)
{
lcd_wdat(line2_data[i]);
Delay_ms(100);
}
LocateXY(0,2); //设置显示位置为第2行第0列
for(i=0;i<16;i++)
{
lcd_wdat(line3_data[i]);
Delay_ms(100);
}
LocateXY(0,3); //设置显示位置为第3行第0列
for(i=0;i<16;i++)
{
lcd_wdat(line4_data[i]);
Delay_ms(100);
}
Delay_ms(1000); //停留1s
lcd_flash(); //闪烁三次
lcd_clr(); //清屏
Delay_ms(2000);
}
}
今天的文章 ettercap 0.8.3教程(ettercap0.8.3.1)分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/bian-cheng-ri-ji/37455.html