新北高工
106 工科技藝競賽電腦修護
第二站研習
主講人:
聖約翰科技大學資工系鄭林合
lhjeng@mail.sju.edu.tw
Contents
• Introduction to競賽電路
• 競賽準備重點
• Introduction to ATMEGA8
• ATMEGA8 程式設計,編譯,燒錄說明
• LCD(1602) 控制時序與指令格式
• LCD(1602)控制程式撰寫
• VB USB 通訊設計
• 實地演練
• Q&A
Introduction to競賽電路
2 3 5 26 27 28 23 24 25 11 1Introduction to競賽電路
周邊:
•
4X3 key array
•
1602 LCD
•
Passive Buzzer
•
Waveform output
•
Simulated USB interface
•
Background Timer
競賽準備重點
4X3 key array:
• 單鍵輸入辨識
• 雙鍵同時輸入辨識
• 長、短按事件辨識
• 持續按事件辨識
• De-bounce
• key scan process
• Row
• Column
競賽準備重點
1602 LCD
• 在指定位置顯示指定文字
• 游標控制
• 自建字型
• 自建字型 > 8 組時
• 跑馬燈
• 視窗控制
競賽準備重點
Passive Buzzer, waveform output
• Software waveform generate
• Polling
• Interrupts
• Timer/Counters
用法
競賽準備重點
Simulated USB interface
VB-> 介面卡
OutDataEightByte
a, b, c, d, e, f, g, h
ReadData
ReadKeyData
// ReadKeyData[8]
'
介面卡-> VB
讀入
usbFunctionWrite
(uchar *data, uchar len) //PC write
*(data) <=
a
*(data+1)<=
b
*(data+2)<=
c
寫出
usbFunctionRead
(uchar *data, uchar len) // PC read
*(data) = keyin;
// 要傳給VB的第一個位元組
ReadKeyData[1]
*(data+1) = 0;
//要傳給VB的第二個位元組
ReadKeyData[2]
競賽準備重點
Background Timer
• 餵狗
• 掃描鍵盤
• 產生介面卡顯示時間
• 鍵盤長按
、
短按
、
隨便按的時間
• 控制協調介面卡功能
// timer0 overflow interrupt
ISR (TIMER0_OVF_vect)
{
uchar i;
wdt_reset();
keyScan();
setSystemTime;
for(i=0;i<4;i++){
if(timer[i]>0)
timer[i]--;
}
}
Introduction to
ATMEGA8
• Advanced RISC Architecture
• 8Kbytes Flash
• 512Bytes EEPROM
• 1Kbyte Internal SRAM
• Write/Erase Cycles:
10,000 Flash/100,000 EEPROM
• GPIOs
• Two 8-bit,One 16-bit
Timer/Counter with
Separate Prescaler, Compare Mode, and Capture Mode
• Programmable Watchdog Timer
• Three PWM Channels
• 6-channel 10-bit Accuracy
• Byte-oriented Two-wire Serial Interface
• Programmable Serial USART
• Master/Slave SPI Serial Interface
• On-chip Analog Comparator
Introduction toATMEGA8
• GPIOs
• Two 8-bit,One 16-bit
Timer/Counter
………..only
ATMEGA8 程式設計,編譯,燒錄說明
• ATMEGA8
• Compiler
–
• Editor
–
• Programmer
–
• 其他免錢的都可以用………..
• GPIO
• Timer/Counter
• AD/DA (not used this time)
• Interrupt
LCD(1602) 控制時序
與指令格式
LCD(1602)控制程式撰寫
從LCD規格書可知:
1. 在
E
腳的
負緣( High->Low ),
LCD開始讀寫動作
2. 每一個指令執行完成需要38us
3. 我設定指令時間為40us
4. 用#define 設計基本指令
#define LcdData(A) {
PORTB&=0xC0;PORTB|=(0x3F&A);PORTD&=0x3F;PORTD|=(0xC0&A)
;}
//依題目規定DATA 分在PORTB 跟 PORTD 上,需要先接合
#define writeLCMC(B) {LcdData(B);PORTD&=0xFC;PORTD|=0x08;TCNT2=0;while(TCNT2<10);PORTD&=0xF7;_delay_us(40);}
// 依規格書波形規定執行完命令後,
等待40us
#define writeLCMD(B) {LcdData(B);PORTD&=0xFD;PORTD|=0x09;TCNT2=0;while(TCNT2<10);PORTD&=0xF7;_delay_us(40);}
LCD(1602)控制程式撰寫
1. LCD 初始化需要久一點的時間,等待系統穩定
2. 初始化過後就可以依規格書執行
/* ---LCM 初始化--- */ void InitLCM(void){ writeLCMC(0x38) //lcd_FunctionReset _delay_ms(5);writeLCMC(0x0F) //Cursor set _delay_ms(5); writeLCMC(0x01) //lcd_FunctionSet _delay_ms(5); writeLCMC(0x06) //lcd_FunctionSet}
/* ---寫一個字串到LCD--- */
void writeLCMstr(uchar *p){
uchar lcnt=0;
do{writeLCMD(*(p+lcnt));
}while(*(p+(lcnt++)));
}
/* ---寫一個位元組到CGM--- */
void writeCGM(uchar p,uchar *data){
uchar i,k;
k=0x40+(p<<3);
writeLCMC(k) //set CGM address
for(i=0;i<0x8;i++){
//write 8 Bytes
k=*(data+i);
writeLCMD(k)
}}
寫一byte 到LCD 命令波形(43us)
writeLCMD(B)
E
Data Bus
寫一個字串到LCD 命令波形
(void writeLCMstr(uchar *p))
寫一個字串到LCD 命令波形
(void writeLCMstr(uchar *p))
執行LCD 命令的延遲(40us)
_delay_us(40);
void keyScan(void){
if(~PINC&0x78) //key pressed switch(keyIndex){
case 0:
if(~PINC&0x08) key_in=1; else if(~PINC&0x10) key_in=4; else if(~PINC&0x20) key_in=7; else if(~PINC&0x40) key_in=10; break;
case 1:
if(~PINC&0x08) key_in=2; else if(~PINC&0x10) key_in=5; else if(~PINC&0x20) key_in=8; else if(~PINC&0x40) key_in=11; break;
case 2:
if(~PINC&0x08) key_in=3; else if(~PINC&0x10) key_in=6;
else if(~PINC&0x20) key_in=9; PINC else if(~PINC&0x20) key_in=0;
break; default: key_in=0; } if(++keyIndex>2)keyIndex=0; PORTC|=0x07; PORTC&=~(0x01<<keyIndex);}