|
本人最近做一个基于avr单片机简易的交通灯系统,原定的功能是在交通灯正常运行时12864显示屏显示“交通灯正常运行”,代码写出来之后仿真也未出现问题,把程序烧进实物之后发现12864显示虽然亮了,但屏上未显示内容,而重复多次复位操作后发现有时会显示几个正确字符,但存在乱码。经百度后判断是时序问题,我修改了多次延时之后都没能让12864正常显示,现问下各位大佬怎么调整时序,以让12864正常运行?
单片机源程序如下:
- #define F_CPU 8000000UL
- #include <avr/io.h>
- #include <util/delay.h>
- #include <string.h>
- #define uchar unsigned char
- #define uint unsigned int
- #define RS (1<<5)
- #define RW (1<<6)
- #define EN (1<<7)
- #define delay_ms(x) _delay_ms(x)
- #define RED_1 (1<<0)
- #define RED_2 (1<<3)
- #define YEL_1 (1<<1)
- #define YEL_2 (1<<4)
- #define GREEN_1 (1<<2)
- #define GREEN_2 (1<<5)
- //此处定义字符串
- char text_1[]={"交通灯正常运行中"};
- char text_2[]={" 紧急模式"};
- char text_3[]={"调整间断模式"};
- char text_4[]={"红灯"};
- char text_5[]={"黄灯"};
- char red_time[]={"05s"};
- char YEL_time[]={"07ms"};
- int emer = 0;
- int adju = 0;
- int key = 0;
- int staus = 0;
- int n=9,Yel_time=7;
- void EEPROM_write(unsigned int uiAddress, unsigned char ucData)
- {
- /* 等待上一次写操作结束 */
- while(EECR & (1<<EEWE))
- ;
- /* 设置地址和数据寄存器 */
- EEAR = uiAddress;
- EEDR = ucData;
- /* 置位 EEMWE */
- EECR |= (1<<EEMWE);
- /* 置位 EEWE 以启动写操作 E */
- EECR |= (1<<EEWE);
- }
- unsigned char EEPROM_read(unsigned int uiAddress)
- {
- /* 等待上一次写操作结束 */
- while(EECR & (1<<EEWE))
- ;
- /* 设置地址寄存器 */
- EEAR = uiAddress;
- /* 设置 EERE 以启动读操作 */
- EECR |= (1<<EERE);
- /* 自数据寄存器返回数据 */
- return EEDR;
- }
- int key_board(void) {
- unsigned char i,j; //键码记录
- unsigned char key_num=0; //按键表示的数字
- i=PIND&0xF3;
- if (i == 0xF3) return key_num; //无按键按下,退出
- delay_ms(10); //去按键颤抖
- j = PIND&0xF3;
- if(i == j) { //二次对比确定按键操作
- switch (i) { //将按键码转换成键值
- case 0xF2: key_num=1;break;
- case 0xF1: key_num=2;break;
- case 0xE3: key_num=3;break;
- case 0xD3: key_num=4;break;
- case 0xB3: key_num=5;break;
- case 0x73: key_num=6;break;
- default: key_num=0;break;
- }
- }
- while(PIND!=0xF3); //等待按键松开
- return key_num;
- }
- void emer_mode(){
- int a=1;
- WriteCommandLCM(0x01);
- PORTC=(RED_1)|(RED_2);
- PORTA=(GREEN_1)|(GREEN_2);
- DisplayList(0x80,text_2);
- while(a){
- key=key_board();
- if (key)
- {
- a=0;
- key=1;
- WriteCommandLCM(0x01);
- s_ms(100);
- DisplayList(0x80,text_1);
- }
- }
- }
- void adju_mode(){
- staus = 1;
- int real_time;
- int sit = 0,sel=3;
- unsigned char poab,pocb;
- pocb=PORTC;
- poab=PORTA;
- real_time=n-4;
- WriteCommandLCM(0x01);
- DisplayList(0x80,text_3);
- DisplayList(0x90,text_4);
- DisplayList(0x95,text_5);
- red_time[0]=(real_time/10)+48;
- red_time[1]=(real_time%10)+48;
- YEL_time[0]=(Yel_time/10)+48;
- YEL_time[1]=(Yel_time%10)+48;
- DisplayList(0x88,red_time);
- DisplayList(0x8D,YEL_time);
- PORTC=(RED_1)|(RED_2);
- PORTA=(GREEN_1)|(GREEN_2);
- while(staus){
- delay_ms(200);
- sit=key_board();
- if (sit==3)
- {
- sel=sit;
- PORTC=(RED_1)|(RED_2);
- PORTA=(GREEN_1)|(GREEN_2);
- }
- else if (sit==4)
- {
- sel=sit;
- PORTC=(YEL_1)|(YEL_2);
- PORTA=(YEL_1)|(YEL_2);
- }
- if (sel==3)
- {
- PORTC^=(RED_1)|(RED_2);
- PORTA^=(GREEN_1)|(GREEN_2);
- }
- else if (sel==4)
- {
- PORTC^=(YEL_1)|(YEL_2);
- PORTA^=(YEL_1)|(YEL_2);
- }
- if (sit==5&&sel==3)
- {
- n++;
- delay_ms(100);
- if (n-4>15)
- {
- n=9;
- }
- EEPROM_write(0x00,n);
- real_time=n-4;
- red_time[0]=(real_time/10)+48;
- red_time[1]=(real_time%10)+48;
- DisplayList(0x88,red_time);
- }
- else if (sit==6&&sel==3)
- {
- n--;
- delay_ms(100);
- if (n-4<5)
- {
- n=19;
- }
- EEPROM_write(0x00,n);
- real_time=n-4;
- red_time[0]=(real_time/10)+48;
- red_time[1]=(real_time%10)+48;
- DisplayList(0x88,red_time);
- }
- if (sit==5&&sel==4)
- {
- Yel_time++;
- delay_ms(100);
- if (Yel_time>20)
- {
- Yel_time=5;
- }
- EEPROM_write(0x08,Yel_time);
- YEL_time[0]=(Yel_time/10)+48;
- YEL_time[1]=(Yel_time%10)+48;
- DisplayList(0x8D,YEL_time);
- }
- else if (sit==6&&sel==4)
- {
- Yel_time--;
- delay_ms(100);
- if (Yel_time<5)
- {
- Yel_time=20;
- }
- EEPROM_write(0x08,Yel_time);
- YEL_time[0]=(Yel_time/10)+48;
- YEL_time[1]=(Yel_time%10)+48;
- DisplayList(0x8D,YEL_time);
- }
- if (sit==2)
- {
- WriteCommandLCM(0x01);
- s_ms(100);
- DisplayList(0x80,text_1);
- PORTA=poab;
- PORTC=pocb;
- staus=0;
- }
- }
- }
- void get_key(){
- int sel=0;
- sel=key_board();
- if (sel==1)
- {
- emer_mode();
- }
- else if (sel==2)
- {
- adju_mode();
- }
- }
- //延时函数
- void s_ms(uint ms)
- {
- int a;
- for (a=0;a<1;a++)
- {
- for(;ms>1;ms--);
- }
- }
- //写数据
- void WriteDataLCM(unsigned char WDLCM)
- {
- ReadStatusLCM(); //检测忙
- s_ms(100);
- PORTE|=RS; //RS=1
- s_ms(100);
- PORTE&=~RW; //RW=0
- s_ms(100);
- PORTE|=EN; //EN=1
- s_ms(100);
- PORTB=WDLCM; //输出数据
- s_ms(100);
- PORTE&=~EN; //EN=0
- s_ms(100);
- }
- //写指令
- void WriteCommandLCM(unsigned char WCLCM)
- {
- ReadStatusLCM(); //根据需要检测忙
- s_ms(100);
- PORTE&=~RS; //RS=0
- s_ms(100);
- PORTE&=~RW; //RW=0
- s_ms(100);
- PORTE|=EN; //EN=1
- s_ms(100);
- PORTB=WCLCM; //输出指令
- s_ms(100);
- PORTE&=~EN; //EN=0
- s_ms(100);
- }
- //读状态:检测忙
- void ReadStatusLCM(void)
- {
- uchar temp;
- uchar flag = 1;
- while(flag==1)
- {
- DDRB=0x00; //端口B改为输入
- PORTB=0xff;
- s_ms(100);
- PORTE&=~RS; //RS=0
- s_ms(100);
- PORTE|=RW; //RW=1
- s_ms(100);
- PORTE|=EN; //EN=1
- s_ms(1000);
- temp = PINB; //读端口B
- s_ms(1000);
- DDRB=0xff; //端口B改为
- s_ms(100);
- PORTE&=~EN; //EN=0
- s_ms(100);
- if(temp>>7==0)
- flag = 0;
- return;
- }
- }
- //LCM初始化
- void LCMInit(void)
- {
- WriteCommandLCM(0x38); //三次显示模式设置,不检测忙信号
- s_ms(1000);
- WriteCommandLCM(0x38);
- s_ms(1000);
- WriteCommandLCM(0x38);
- s_ms(1000);
- WriteCommandLCM(0x38); //显示模式设置,开始要求每次检测忙信号
- WriteCommandLCM(0x08); //关闭显示
- WriteCommandLCM(0x01); //显示清屏
- WriteCommandLCM(0x06); //显示光标移动设置
- WriteCommandLCM(0x0C); //显示开及光标设置
- }
- //按指定位置显示一串字符
- //液晶显示:汉字为16*16,字母及数字为8*16,此次显示的文本
- // 从第一行第一列开始,依次向左,如果想在不同的
- // 位置显示,只需修改相应的行值即可。液晶显示
- // 完毕后,转入语音文本发送。
- //DisplsyList(X,DData)函数:X为0x80在第一行显示;X为0x90在
- // 第二行显示;X为0x88在第三行显示;X为0x98在
- // 第四行显示;DData为显示数组。
- void DisplayList(unsigned char X,char *DData)
- {
- unsigned char length;
- unsigned char i=0;
- char *p;
- p = DData;
- length = strlen(p);
- WriteCommandLCM(0x08);
- WriteCommandLCM(X);
- WriteCommandLCM(0x06);
- WriteCommandLCM(0x0C);
- WriteCommandLCM(X);
- for(i=0;i<length;i++)
- {
- WriteDataLCM(DData[i]);
- i++;
- WriteDataLCM(DData[i]);
- }
- }
- void Init(){
- DDRA|=~((1<<6)|(1<<7));
- DDRC|=~((1<<6)|(1<<7));
- PORTC|=(RED_1)|(RED_2);
- PORTA|=(GREEN_1)|(GREEN_2);
- //端口初始化
- DDRB=0xff;
- PORTB=0xff;
- DDRG=(1<<3)|(1<<4);
- PORTG=(1<<3)|(1<<4);
- DDRE|=RW|RS|EN;
- PORTE|=RW|RS|EN;
- DDRD|=(0<<0)|(0<<1)|(0<<4)|(0<<5)|(0<<6)|(0<<7);
- PORTD|=(1<<0)|(1<<1)|(1<<4)|(1<<5)|(1<<6)|(1<<7);
- s_ms(200);
- s_ms(200);
- LCMInit(); //LCM初始化
- }
- int main(void)
- {
- int a,b=0,c=0,time=10;
- int im;
- int chf=1;
- Init();
- ReadStatusLCM();
- DisplayList(0x80,text_1); //显示初始界面
- s_ms(100);
- im=EEPROM_read(0x10);
- if (im)
- {
- EEPROM_write(0x00,n);
- EEPROM_write(0x08,Yel_time);
- EEPROM_write(0x10,0);
- }
- n=EEPROM_read(0x00);
- Yel_time=EEPROM_read(0x08);
- while(1)
- {
- while(chf==0)
- {
- for (a=0;a<n;a++)
- {
- if (b==0)
- {
- PORTA=(GREEN_1)|(RED_2);
- while(a>=n-5&&a<n){
- for (;a<n;a++)
- {
- get_key();
- PORTA^=(RED_2);
- delay_ms(200);
- }
- PORTA=(YEL_2)|(GREEN_1);
- for(c=0;c<Yel_time;c++)
- {
- get_key();
- delay_ms(100);
- }
- }
- }
- else if (b==1)
- {
- PORTA=(RED_1)|(GREEN_2);
- while(a>=n-5&&a<n){
- for (;a<n;a++)
- {
- get_key();
- PORTA^=(RED_1);
- delay_ms(200);
- }
- PORTA=(YEL_1)|(GREEN_2);
- for(c=0;c<Yel_time;c++)
- {
- get_key();
- delay_ms(100);
- }
- PORTA=(GREEN_1)|(GREEN_2);
- chf=1;
- PORTC=(GREEN_1)|(RED_2);
- }
- }
- for(c=0;c<time;c++)
- {
- get_key();
- delay_ms(100);
- }
- }
- b=(++b)%2;
- }
- while(chf==1)
- {
- for (a=0;a<n;a++)
- {
- if (b==0)
- {
- PORTC=(GREEN_1)|(RED_2);
- while(a>=n-5&&a<n){
- for (;a<n;a++)
- {
- get_key();
- PORTC^=(GREEN_1);
- delay_ms(200);
- }
- PORTC=(YEL_1)|(RED_2);
- for(c=0;c<Yel_time;c++)
- {
- get_key();
- delay_ms(100);
- }
- }
- }
- else if (b==1)
- {
- PORTC=(RED_1)|(GREEN_2);
- while(a>=n-5&&a<n){
- for (;a<n;a++)
- {
- get_key();
- PORTC^=(GREEN_2);
- delay_ms(200);
- }
- PORTC=(YEL_2)|(RED_1);
- for(c=0;c<Yel_time;c++)
- {
- get_key();
- delay_ms(100);
- }
- PORTC=(RED_1)|(RED_2);
- chf=0;
- PORTA=(GREEN_1)|(RED_2);
- }
- }
- for(c=0;c<time;c++)
- {
- get_key();
- delay_ms(100);
- }
- }
- b=(++b)%2;
- }
- }
- }
复制代码 |
-
-
01.7z
22.3 KB, 下载次数: 6
程序及电路图
|