|
本人最近做一個基于avr單片機簡易的交通燈系統,原定的功能是在交通燈正常運行時12864顯示屏顯示“交通燈正常運行”,代碼寫出來之后仿真也未出現問題,把程序燒進實物之后發現12864顯示雖然亮了,但屏上未顯示內容,而重復多次復位操作后發現有時會顯示幾個正確字符,但存在亂碼。經百度后判斷是時序問題,我修改了多次延時之后都沒能讓12864正常顯示,現問下各位大佬怎么調整時序,以讓12864正常運行?
1.png (112.75 KB, 下載次數: 18)
下載附件
2022-3-26 23:07 上傳
2.jpg (686.28 KB, 下載次數: 20)
下載附件
2022-3-26 23:07 上傳
單片機源程序如下:
- #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
2022-3-26 23:07 上傳
點擊文件名下載附件
22.3 KB, 下載次數: 6
程序及電路圖
|