⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main._c

📁 AVR试验板程序,有LED,键盘和串口的程序
💻 _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=tmp_PD&(~(0X78)); break;     //0111 10  00 代码
//case 0X82: PORTD=tmp_PD&(~(0XD4)); break;     //1011 01  00 代码
//case 0X83: PORTD=tmp_PD&(~(0XCC)); break;     //1100 11  00 代码
//case 0X84: PORTD=tmp_PD&(~(0XCC)); break;     //1100 11  00 代码
//case 0X85: PORTD=tmp_PD&(~(0XD4)); break;     //1011 01  00 代码
//case 0X86: PORTD=tmp_PD&(~(0X78)); break;     //0111 10  00 代码


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 + -