?? main.c
字號:
//ICC-AVR application builder : 2007-2-22 12:20:11
// Target : M16
// Crystal: 10.000Mhz
#include <iom16v.h>
#include <macros.h>
unsigned char tmp_cn_0; //臨時計數器——0
unsigned char tmp_cn_1; //臨時計數器——1
unsigned char led_ch=0x80; //閃爍的花樣
unsigned char key_code; //鍵盤按下的鍵盤代碼
unsigned char tmp_led_index=0x00;
unsigned char const LED_INDEX[]={0X3F,0X06,0X5B,0X4F,
0X66,0X6D,0X7D,0X07,
0X7F,0X6F};//共陰管的數字0-9的代碼
void port_init(void)
{
PORTA = 0xC0;
DDRA = 0xC0; //高2位作為10位ADC的MSB,低2位用外部ADC輸入,其余用于鍵盤的輸入
PORTB = 0xFF;
DDRB = 0xFF; //驅動靜態595顯示,只用到高4位,低四位保留
PORTC = 0xFF; //m103 output only
DDRC = 0xFF; //ADC的低8位輸出
PORTD = 0xFF;
DDRD = 0xFF; //高6位用于顯示LED,低2位用于串口的輸出。
}
//TIMER0 initialize - prescale:256
// WGM: Normal
// desired value: 2mSec
// actual value: 1.997mSec (0.2%)
void timer0_init(void) //硬件計數器0的初始化程序
{
TCCR0 = 0x00; //stop
TCNT0 = 0xB2; //set count
OCR0 = 0x4E; //set compare
TCCR0 = 0x04; //start timer
}
/*-----------------------ADC轉換初始化----------------------------------------*/
//ADC initialize
// Conversion time: 26uS
void adc_init(void)
{
ADCSR = 0x00; //disable adc
ADMUX = 0x00; //選擇外部基準電壓 通道 0 輸入
ACSR = 0xC0; //模擬比較器控制和狀態寄存器 ACSR
//ACD置1,使模擬比較器禁用
/*--ACD--ACBG--ACO--ACI---ACIE---ACIC---ACIS1---ACIS0------------------------*/
/*-模擬比較起禁用--模擬比較器的能隙基準源--模擬比較起輸出--模擬比較器中斷標志*/
/*-模擬比較器中斷使能--模擬比較器輸入捕捉使能--模擬比較器中斷模式選擇--------*/
ADCSR = 0x8B;//模擬比較起控制和狀態寄存器
/*-----------ADEN---ADSC---ADFR---ADIF---ADIE---ADPS2---ADPS1---ADPS0--------*/
//使能模數轉換 ADC開始轉換 ADC連續轉換 ADC中斷使能 128分頻
}
/*-----------------------ADC轉換中斷程序--------------------------------------*/
#pragma interrupt_handler adc_isr:15
void adc_isr(void) //組合輸出ADC DATA
{
unsigned char rr=0;
//conversion complete, read value (int) using...
PORTC=~(ADCL); //c口顯示低8位的信息 (反相)
rr =ADCH<<6; //高8位的信息
rr ^=(0x03<<6); //反相
PORTA=rr; //在A口高2位顯示
}
void start_adc_0(void) //啟動ADC轉換的程序
{
ADMUX = 0x00; //選擇通道0
ADCSR |= 0x40; //開始ADC轉換
}
//SPI initialize //初始化硬件SPIS口的程序
// clock rate: 2500000hz
void spi_init(void)
{
SPCR = 0x50; //setup SPI
SPSR = 0x00; //setup SPI
}
void SPI_595_Out(unsigned char i) //HC595數據的輸出
{
SPDR = i; /* 啟動數據傳輸 */
while (!(SPSR & (1<<SPIF))); //等待傳輸結束
}
void disp_led(unsigned char i)
{
PORTB &= ~(1 << PB4); //準備鎖存,在全部的四個LED數據送完后再鎖存
SPI_595_Out(i);
PORTB |= (1 << PB4); //在這個時候鎖存數據 顯示
}
//UART0 initialize //初始化串口0的程序
// desired baud rate: 9600
// actual: baud rate:9615 (0.2%)
// char size: 8 bit 沒有校驗位
// parity: Disabled
void uart0_init(void)
{
UCSRB = 0x00; //disable while setting baud rate
UCSRA = 0x00;
UCSRC = BIT(URSEL) | 0x06;
UBRRL = 0x40; //set baud rate lo
UBRRH = 0x00; //set baud rate hi
UCSRB = 0x98;
}
void USART_Transmit( unsigned char data )
{
while ( !( UCSRA & (1<<UDRE)) ) // 等待發送緩沖器為空
;
UDR = data; //將數據放入緩沖器,發送數據
}
unsigned char USART_Receive(void) //使用中斷接受時不用此函數
{
while ( !(UCSRA & (1<<RXC)) ) // 等待接收數據
;
return UDR; // 從緩沖器中獲取并返回數據
}
#pragma interrupt_handler uart0_rx_isr:12
void uart0_rx_isr(void) //串口0的中斷服務程序
{
USART_Transmit(UDR); //把接收到的數據重新發回給PC機
}
//call this routine to initialize all peripherals
void init_devices(void)
{
//stop errant interrupts until set up
CLI(); //disable all interrupts
port_init();
timer0_init();
uart0_init();
spi_init();
adc_init();
MCUCR = 0x00;
GICR = 0x00;
ASSR &= ~(0X08);
TIMSK = 0x01; //timer interrupt sources
SEI(); //re-enable interrupts
//all peripherals are now initialized
}
void flash_led_type1(void) //PD口的跑馬燈顯示 從右到左
{
if (led_ch==0x02) led_ch=0x80;
PORTD=~(led_ch);
led_ch=led_ch>>1;
}
void flash_led_type2(void) //PD口的跑馬燈顯示 從左到右
{
if (led_ch==0x00) led_ch=0x02;
PORTD=~(led_ch);
led_ch=led_ch<<1;
}
void flash_led_type3(void) //PD口的跑馬燈顯示 反相
{
PORTD^=0XFC;
}
void flash_led_type4(void) //PD口的跑馬燈顯示 流水
{
unsigned char tmp_PD;
tmp_PD=PIND;
tmp_PD|=0XFC;
led_ch++;
if (led_ch==0X87) led_ch=0X80;
switch (led_ch)
{
case 0X81: PORTD=~(0X78); break; //0111 10 00 代碼
case 0X82: PORTD=~(0XD4); break; //1011 01 00 代碼
case 0X83: PORTD=~(0XCC); break; //1100 11 00 代碼
case 0X84: PORTD=~(0XCC); break; //1100 11 00 代碼
case 0X85: PORTD=~(0XD4); break; //1011 01 00 代碼
case 0X86: PORTD=~(0X78); break; //0111 10 00 代碼
}
}
void delay30ms(void) //延時30毫秒的子程序
{
unsigned int tmp_delay_cn;
for (tmp_delay_cn=0;tmp_delay_cn<300;tmp_delay_cn++)
;
}
unsigned char check_key_pressed(void) //檢查是否有鍵盤按下
{
unsigned char key_tem;
key_tem=PINA &= ~(0XC3);
if(key_tem!=0X3C)
return 1;
else
return 0;
}
unsigned char find_key_code(void)
{
unsigned char uuu;
if(check_key_pressed()==1)
{
delay30ms(); //延時去抖動
if(check_key_pressed()==1)
{
uuu=(PINA & 0X3C);
return uuu; //屏蔽最高和最低兩位
}
}
return 0XC3;
}
#pragma interrupt_handler timer0_ovf_isr:10 //
void timer0_ovf_isr(void)
{
TCNT0 = 0xB2; //計數器初始值重載
if (tmp_cn_0==100) //固定時間產生變化
{
switch (key_code) //根據按下的鍵盤產生一定的閃燈花樣
{
case 0X1C: flash_led_type4(); break;
case 0X2c: flash_led_type3(); break;
case 0X34: flash_led_type2(); break;
case 0X38: flash_led_type1(); break;
default: flash_led_type4(); break;
}
disp_led(LED_INDEX[tmp_led_index]); //循環顯示8段數字LED
tmp_led_index++;
if (tmp_led_index==10) tmp_led_index=0; //LED計數器歸零
tmp_cn_0=0; //臨時計數器0歸零
}
else
{
tmp_cn_0=tmp_cn_0+1; //臨時計數器遞增
}
}
//****************** MAIN 程序的入口*************************//
void main()
{
unsigned char tmp_key_code;
init_devices();
while(1)
{
start_adc_0(); //循環進行ADC轉換
tmp_key_code=find_key_code() & 0X3C; //判斷是否按下鍵盤
if (tmp_key_code!=0x3c) key_code=tmp_key_code;
}
}
//****************** MAIN 程序結束 *************************//
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -