/*----------------------C语言示例-----------------------* *硬件连接:PTB-HD44780data,PTC0-RS,PTC1-RW,PTC2-E * *程序描述: 1.以串行中断方式接收从PC机发送来的时钟启 * * 动信号56H和时间值 * * v11:11:11:11表示11:11:11 * * 2.以定时中断方式实现实现1秒的定时 * * 3.以串行接受中断方式接受从PC机发送来的时 * * 钟停止信号57H并向PC方发送当前的时钟数据 * *使用模块: 定时模块、串行通信模块及LCD模块 * *------------------------------------------------------*/ #define main_c #i nclude "main.h" //本模块头文件 #i nclude "lcd.h" //其它模块头文件 #i nclude "interrupt.h" //其它模块头文件 //---------------主程序全局变量定义-------------------- unsigned char time[9]= "12:00:00"; const unsigned char info[17]= "HoHai university"; //---------------------------------------------------- void main(void) { DisableInterrupts; //禁止所有中断 init_con(); //系统初始化 DDRA=0xff; //I/O初始化 DDRB=0xff; DDRC=0x17; init_timer1(); //定时器1初始化 init_sci(); //[SCI初始化] Init_HD44780(0b00111100); //LCD初始化 print1L(time); //显示时间初值 print2L(info); //显示其它信息 EnableInterrupts; //开中断 for(;;){ }; } //=================================================================== //= 函数原型: void init_con(void) //= 功 能: 系统配置及时钟初始化 //= 参 数: 无 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void init_con(void) { } //=================================================================== //= 函数原型: void init_timer1(void) //= 功 能: 初始化定时器1 //= 参 数: 无 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void init_timer1(void) { T1SC=0b01100110; //01100110允许溢出中断、 //不启动计数、分频因子=64 T1CNTH=0; //计数器初值清0 T1CNTL=0; T1MODH=0x96; //设1秒产生1次溢出中断 T1MODL=0; //模数寄存器设定值= //1×(2457600/64)=$9600 } //=================================================================== //= 函数原型: void init_sci(void) //= 功 能: 初始化串口 //= 参 数: 无 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void init_sci(void) { //监控程序已初始化一部分 SCC2=0x2c; //设置接收中断允许 } main.h #ifndef main_h //防止在同一模块多次包含 #define main_h #i nclude "head.h" //本工程公共头文件 #i nclude //系统头文件,包含开关中断 #i nclude //芯片头文件 #ifndef main_c //*********主程序非静态全局变量定义************* extern unsigned char time[]; extern const unsigned char info[]; //自己模块内的全局变量,公共函数声明给其他模块 #else //*********主程序自定义函数说明*** void init_con(void); void init_timer1(void); void init_sci(void); //自己的私有函数和公共函数声明给自己模块 #endif #endif lcd.c #define lcd_c #i nclude "main.h" //其它模块头文件 #i nclude "lcd.h" //本模块头文件 #i nclude "interrupt.h" //其它模块头文件 //=================================================================== //= 函数原型: void DelaySub(INT16U i,INT16U vector) //= 功 能: 延时函数 //= 参 数: 为延时大小,vector为延时矢量 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void DelaySub(INT16U i,INT16U vector) { INT16U j; INT16U x; for(j=0;j<=i;j++) for(x=0;x<=vector;x++); } //=================================================================== //= 函数原型: void AsmDelay(INT8U delaytime) //= 功 能: 延时函数 //= 参 数: 为延时大小 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void AsmDelay(INT8U delaytime) { while(delaytime--) { asm("NOP"); //1 cycles asm("NOP"); //1 cycles } } //=================================================================== //= 函数原型: void LCD_Command(INT8U cmd) //= 功 能: 对A中指令使用PORTB作为输出口, // 到LCD进行命令执行或字符显示 //= 参 数: cmd,执行的指令,8位 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void LCD_Command(INT8U cmd) { AsmDelay(15); //等待约40us PTB=cmd; //把指令码送到B口 asm("NOP"); asm("NOP"); PTC|=0b00000100; //LCD开始接受数据,置使能位为1 asm("NOP"); asm("NOP"); PTC&=0b11111011; //LCD结束接受数据,置使能位为0 AsmDelay(15); //等待约40us } //=================================================================== //= 函数原型: void Init_HD44780(INT8U setting) //= 功 能: 初始化HD44780 //= 参 数: "HD44780功能"设置命令 //= 返 回 值: 无 //= 函数性质:公有函数 //=================================================================== void Init_HD44780(INT8U setting) { PTC&=0b11111110; //令LCD的RS=0,R/W=0, //进行LCD初始化 PTC&=0b11111101; //功能设置:数据接口,显示行数,点阵模式 //00111000:8位数据接口,2行显示,5*7点阵模式 //00110100:8位数据接口,1行显示,5*10点阵模式 LCD_Command(setting); //显示开关控制:关显示,关光标显示,不闪烁 LCD_Command(0b00001000); AsmDelay(15); //等待约40us PTC&=0b11111110; //RS,RW清零开始清屏 PTC&=0b11111101; LCD_Command(0b00000001); //清屏指令 DelaySub(1,0x200); //等待清屏完毕,时间>1.6ms //输入方式设置:数据读写操作后, //AC自动增1显示不动,光标左移 LCD_Command(0b00000110); //光标移位设置:光标右移一个字符位,AC自动加1 LCD_Command(0b00010100); //显示开关设置:开显示,关光标显示,不闪烁 LCD_Command(0b00001100); } //=================================================================== //= 函数原型: void print1L(INT8U *s) //= 功 能: HD44780第一行显示 //= 参 数: 欲显示的字符串 //= 返 回 值: 无 //= 函数性质:公有函数 //=================================================================== void print1L(INT8U *s) { INT8U i; i=0; PTC&=0b11111110; PTC&=0b11111101; LCD_Command(0b10000000); while(*s&&i<16){ PTC|=0b00000001; //令LCD的RS=1,R/W=0, //写入数据到DD RAM中 PTC&=0b11111101; LCD_Command(*s); //将要显示的字符串 //分个送到LCD s++; i++; } } //=================================================================== //= 函数原型: void print2L(INT8U *s) //= 功 能: HD44780第二行显示 //= 参 数: 欲显示的字符串 //= 返 回 值: 无 //= 函数性质:公有函数 //=================================================================== void print2L(INT8U *info) { INT8U i; i=0; PTC&=0b11111110; PTC&=0b11111101; LCD_Command(0b11000000); i=0; //如果超过16个字符,将字符全部送完 while(info[i]&&i<16){ PTC|=0b00000001; //令LCD的RS=1,R/W=0, //写入数据到DD RAM中 PTC&=0b11111101; LCD_Command(info[i]); i++; } } lcd.h #ifndef lcd_h //防止在同一模块多次包含 #define lcd_h #i nclude "head.h" //本工程公共头文件 #i nclude //系统头文件,包含开关中断 #i nclude //芯片头文件 #ifndef lcd_c //*********全局变量,公共函数定义************* void Init_HD44780(INT8U setting); void print1L(INT8U *s); void print2L(INT8U *s); //自己模块内的全局变量,公共函数声明给其他模块 #else //*********本模块自定义函数说明*** void DelaySub(INT16U i,INT16U vector); void AsmDelay(INT8U delaytime); void LCD_Command(INT8U cmd); //自己的私有函数和公共函数声明给自己模块 #endif #endif interrupt.c #define interrupt_c #i nclude "main.h" //其它模块头文件 #i nclude "lcd.h" //其它模块头文件 #i nclude "interrupt.h" //本模块头文件 //=================全局变量定义===================================== unsigned char INBUF[8]; //存放PC机发来的8个数据变量 //=================================================================== //=================================================================== //= 函数原型: void SCISend(unsigned char out) //= 功 能: 用SCI发送一个字节 //= 参 数: 要发送的字节 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void SCISend(unsigned char out) { while((SCS1 & 0x80) == 0); //判断SCS1的第7位是否为1, //是表示发送缓冲空,可以发送 SCDR=out; } //=================================================================== //= 函数原型: void MainSend( ) //= 功 能: 接收中断处理函数处理子程序 //= 参 数: 无 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== void MainSend( ) { int i,m; unsigned char hand; for(;;) { //等待接收1个字节的信号,收不到数据退出 m=0; //SCS1第5位为1表示接收缓冲区中有数据可接收 for(i=0;i<0xfff&&((SCS1 & 0x20) == 0);i++); //i=0xfff表示超时未收到数据 if(i==0xfff) continue; hand=SCDR; //接收握手信号86 if(hand==0x56) //收到数据,与86比较: //是,表示计数开始 { T1SC&=0xdf; //允许定时器1计数寄存器计数 //取PC机发来的6个数据暂存INBUF缓冲区 while (m<=0x07) { //SCS1第5位为1表示接收缓冲区中有数据可接收 for(i=0;i<0xfff&&((SCS1 & 0x20) == 0);i++); //i=0xfff表示超时未收到数据 if(i==0xfff)continue; INBUF[m]=SCDR; //读取数据 m=m+1; }; //[显示PC方发来的时钟设置值] //[1.将发来的6个数据转化为字符] for(i=0;i<=7;i++) { time[i]=INBUF[i]; } //[2.显示时钟初始值] print1L((unsigned char*)time); } else if(hand==0x57) //不是86,在与87比较: //是,表示计数结束 { T1SC|=0x20; //不允许定时器1计数寄存器计数 //[发送当前时钟的时间给PC] //1.将SerialBuff中的6个数据由字符转化 //为数值型,并发送给PC for(i=0;i<=7;i++) { SCISend(time[i]); } //2.将发送缓冲区时钟数据发送出去 } break; } } //=================================================================== //= 函数原型: interrupt 13 void isrRec(void) //= 功 能: 接收中断服务函数 //= 参 数: 无 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== interrupt 13 void isrRec(void) { asm("SEI"); //禁止所有中断 MainSend( ); //接收8个数据并返发回PC机方显示 asm("CLI"); //开中断 } //=================================================================== //= 函数原型: interrupt 6 void isrTIMER1(void) //= 功 能: 定时器1溢出处理程序 //= 参 数: 无 //= 返 回 值: 无 //= 函数性质:私有函数 //=================================================================== interrupt 6 void isrTIMER1(void) { asm("SEI"); time[7]=time[7]+1; //秒钟的低位处理 if(time[7]==':') { time[7]='0'; time[6]=time[6]+1; //秒钟的高位处理 if(time[6]=='6') { time[6]='0'; time[4]=time[4]+1; //分钟的低位处理 if(time[4]==':') { time[4]='0'; time[3]=time[3]+1; //分钟的高位处理 if(time[3]=='6') { time[3]='0'; time[1]=time[1]+1;//小时的处理 //与小时的24进行比较处理 if(time[1]=='4') { if(time[0]=='2') { time[1]='0'; time[0]='0'; } } else if(time[1]==':') { time[1]='0'; time[0]=time[0]+1; } } } } } T1SC&=127; //清除定时器溢出标志位 print1L((unsigned char*)time); //显示时间 asm("CLI"); } interrupt.h #ifndef interrupt_h //防止在同一模块多次包含 #define interrupt_h #i nclude "head.h" //本工程公共头文件 #i nclude //系统头文件,包含开关中断 #i nclude //芯片头文件 #ifndef interrupt_c //*********全局变量,公共函数定义************* extern unsigned char INBUF[8]; //存放PC机发来的8个数据变量 //自己模块内的全局变量,公共函数声明给其他模块 #else //*********本模块自定义函数说明*** void SCISend(unsigned char out); void MainSend(); interrupt 13 void isrRec(void); interrupt 6 void isrTIMER1(void); //自己的私有函数和公共函数声明给自己模块 #endif #endif head.h #ifndef _TYPE #define _TYPE typedef unsigned char BOOLEAN; typedef unsigned char INT8U; typedef char INT8S; typedef unsigned int INT16U; typedef int INT16S; typedef unsigned long INT32U; typedef long INT32S; #endif