自己学avr单片机已经有相当一段时间了,一开始用的是atmega128,觉得不是很好用。于是自己去买了一块16L的芯片,觉得还行。一开始用的是ICC AVR,应为它用起来比较简单,不像winavr那样,要写个Makefie
,比较的麻烦,但icc avr的缺点是太过于简陋,调试程序时,感觉不是很好。后来经同学介绍,用起了winavr,其实也是比较的简单,只不过要加一个makefile而已,其实makefile可以用软件自带的组建自动生成,只需修改几个参数就可以用。后来又用起了code vision avr,虽然不太习惯,也谈不上不好用.
需要注意的是,三个不同的软件所带的同文件不一样。icc avr 是(姑且以128为例),winavr是avr/,不过makefile中要设置芯片为atmega128.而cvavr则是。
记得一开始的时候,我对这些不同的同文件不是很理解,是从一个学长那里了解到,才弄明白的。其实前两个软件只需把头文件稍微改一下基本上可以通用。而最后一个软件的中断的写法似乎不太一样,因而和钱两个软件的兼容性是最差的。
总体说winavr给人的感觉是比较专业 自己学习时多总结吧!
1、流水灯 /*
硬件环境:atmega128开发板 软件环境:CodeVisionAVR-C */
#include <>
#define uchar unsigned char #define uint unsigned int
uchar cnt;
void timer1_init() {
TCCR1B=0X00; //先停止定时器1 TCNT1H=0XF0; //设定定时器初值 TCNT1L=0XBE;
TCCR1A=0X00; //启动定时器1 TCCR1B=0X05; //使用1024分频 }
interrupt [TIM1_OVF] void timer1_ovf_isr(void) {
TCNT1H=0XF0; //重载定时器初值 TCNT1L=0XBE; DDRE|=1<<2; PORTE|=1<<2; DDRA=0xff;
PORTA=cnt; //输出led的值到端口B cnt++; if(cnt==255) cnt=0; }
void main() {
//DDRB=0XFF;
SREG|=0X80; TIMSK=0X04; timer1_init(); while(1) {; } }
2、AD转换+数码管显示
/***************************************************************************/ /*ADC测试程
序 */ /*目标器件:ATmega128 */ /*晶振:RC
8MHZ */ /*编译环境:
ICCAVR */ */ /*时间:2010年11月13
日 */
//Aref接AVCC(+5V),采用Aref作参考电压 /*用数码管显示AD转换的结果*/
/***************************************************************************/ /*********************************包含头文件********************************/ #include <> #include <>
/********************************数码管段码表*******************************/ extern const unsigned char tab[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07, 0x7F,0x6F}; /*********************************全局变量**********************************/ unsigned int adc_rel=0;
/**************************************************************************** 函数功能:ADC初始化函数 入口参数: 出口参数:
****************************************************************************/ void adc_init(void) {
DDRF&=0XFE; //PORTF0设置为输入,即作为ADC0口输入模拟电压 PORTF&=0XFE; //PORTF0设置为输入低电平 ADCSRA=0x00; //关ADC
ADMUX = 0X00; //采用Aref作为参考电压,ADC0单端输入,右对齐 ACSR=(1< ****************************************************************************/ #pragma interrupt_handler adc_isr:iv_ADC void adc_isr(void) { //int data_h,data_l; //data_l=ADCL; //data_h=ADCH; ADCSRA = 0x00; ADCSRA = (1< PORTA|=1<<2; } else PORTA&=~(1<<2); */ } /**************************************************************************** 函数功能:延时子程序 入口参数: 出口参数: ****************************************************************************/ void delay(void) { int i; for(i=0;i<1800;i++); } /**************************************************************************** 函数功能:显示子程序 入口参数:k 出口参数: ****************************************************************************/ void display(unsigned int k)//发光二极管显示初始化 { DDRE|=1<<2; PORTE|=1<<2; DDRA=0XFF; PORTA=k; } #define SS 0 #define SCK 1 #define MOSI 2 #define MISO 3 #define SS_H() PORTB|=(1< 开第一个数码管的位选 关第一个数码管的位选 // //#define OE 7 #define point 3 #define dp 7 #include <> #include <> const unsigned char table[]={0x3F,0x06,0x5B,0x4F,0x66, //0,1,2,3,4 0x6D,0x7D,0x07,0x7F,0x6F, //5,6,7,8,9 0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}; //a,b,c,d,e,f volatile unsigned char led_buffer[4]; void delay_1us(void) //1us延时函数 { asm(\"nop\"); } void delay_nus(unsigned int n) //N us延时函数 { unsigned int i=0; for (i=0;i unsigned int i; for (i=0;i<1140;i++); } void delay_nms(unsigned int n) //N ms延时函数 { unsigned int i=0; for (i=0;i DDRB |= (1< void SPI_MasterTransmit(char Data) { /* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */ while(!(SPSR & (1< DDRC |= (1< led_buffer[0]=16; //初始化数码管段码 led_buffer[1]=16; led_buffer[2]=16; led_buffer[3]=16; } /*HC595完成传送数据*/ void HC_595_OUT(unsigned char data) { SS_L(); SPI_MasterTransmit(data); SS_H(); } void leddis_update(void) { /*最低位数码管,第四个数码管*/ if(point==0) HC_595_OUT(table[led_buffer[3]]|(1< if(point==1) HC_595_OUT(table[led_buffer[2]]|(1< if(point==2) HC_595_OUT(table[led_buffer[1]]|(1< /*最高位数码管,第一个数码管*/ if(point==3) HC_595_OUT(table[led_buffer[0]]|(1< void display_led(unsigned int data) { if(data>9999) { HC_595_OUT(0xFF);//当计数大于9999时,四个数码管同时输出8 PORTB|=((1<<4)|(1<<5)|(1<<6)|(1<<7)); } else if(data>999) { led_buffer[0]=data/1000; led_buffer[1]=(data%1000)/100; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else if(data>99) { led_buffer[0]=data/1000; led_buffer[1]=(data%1000)/100; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else if(data>9) //关闭最高位的那个数码管 { led_buffer[0]=data/1000; led_buffer[1]=16; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else { led_buffer[0]=data/1000; led_buffer[1]=16; led_buffer[2]=16; led_buffer[3]=data%10; leddis_update(); } } volatile unsigned int countnum=0; void timer1_init(void) { TCCR1B = 0x00; //stop TCNT1H = 0x8F; //setup TCNT1L = 0x81; OCR1AH = 0x70; OCR1AL = 0x7F; OCR1BH = 0x70; OCR1BL = 0x7F; OCR1CH = 0x70; OCR1CL = 0x7F; ICR1H = 0x70; ICR1L = 0x7F; TCCR1A = 0x00; TCCR1B = 0x04; //start Timer } #pragma interrupt_handler timer1_ovf_isr:15 void timer1_ovf_isr(void) { TCNT1H = 0x8F; //reload counter high value TCNT1L = 0x81; //reload counter low value countnum++; if(countnum>9999) countnum=0; } void init_devices(void) { CLI(); //disable all interrupts timer1_init(); TIMSK = 0x04; //timer interrupt sources SEI(); //re-enable interrupts } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main(void) { init_devices(); HC_595_init(); adc_init(); SEI();//开全局中断变量 display(0); while(1) { delay(); display_led(adc_rel/*5*1000); } } 3、对EEPROM进行读写操作 /************************************************ 文件: 用途: 注意:内部8M晶振 ************************************************/ #include \"\" /*向EEPROM里面写入数据 输入量:地址,数据*/ void EEPROM_write(unsigned int uiAddress,unsigned char ucData) { while(EECR&(1< while(EECR&(1< void main(void) { unsigned char temp=123; unsigned char data; HC_595_init(); EEPROM_write(0x01,temp); data=EEPROM_read(0x01); while(1) { Seg7_Led_display(data); //调用显示函数将写入的数据又读出来 } } 文件: 大小: 40KB 下载: 下载 4、定时器0(轮循方式) /*定时器0和2(均为八位的定时计数器)有四种工作模式,此例是工作在普通模式。 在此模式下,计数器不断的累加,当计数到最大值0xff后返回到0x00重新开始,在TCNT0 为0 的同时,T/C溢出标志TOV0置位*/ //使用轮循方式,当TIFR溢出时,uc_led加1,输出到led时期发光 //TIFR中断标志寄存器 #include <> #define uchar unsigned char uchar uc_led,k; void main() { //设置数码管输出高电平 DDRE|=1<<2; PORTE|=1<<2; DDRA=0XFF; PORTF=0XFF; TCNT0=0X00;//设定定时计数器的初值为0 TCCR0=0X05;//使用1024分频(共有7种时钟) uc_led=0; k=0; while(1) { while(!(TIFR&0X01));//循环检测TIFR中的溢出标志是否有效 //PORTA=uc_led; uc_led++; if(uc_led==255) {uc_led=0; k++; if(k==255) k=0; PORTA=k; } TIFR|=0X01; //写1到TIFR的TOV0位清除溢出标志为TOV0 } } 5、定时器0中中断 /***************************************************************************/ /*定时器T0测试程 序 */ /*目标器件:ATmega128 */ /*晶振:RC 8MHZ */ /*编译环境: ICCAVR */ */ /*时间:2010年3月14 日 */ /*TCCRn定时计数器控制寄存器 TCNTn计数器,不断的计数 TIMSK定时计数器中断屏蔽寄存器 TIFR中断标志寄存器 */ /***************************************************************************/ /*********************************包含头文件********************************/ #include <> #include <> /**********************************全局变量*********************************/ int k; /**************************************************************************** 函数功能:端口初始化程序 入口参数: 出口参数: ****************************************************************************/ void port_init (void) { DDRE|=1<<2; PORTE|=1<<2; DDRA=0XFF; PORTA=0XFF; } /**************************************************************************** 函数功能:定时器初始化程序 入口参数: 出口参数: ****************************************************************************/ void timer0_init(void) { TCCR0 = 0x00; //stop ASSR = 0x00; //set async mode TCNT0 = 0x3c; OCR0 = 0x00; TCCR0 = 0x05; //1024分频 } /**************************************************************************** 函数功能:定时中断服务程序 入口参数: 出口参数: ****************************************************************************/ #pragma interrupt_handler timer0_ovf_isr:17 void timer0_ovf_isr(void) { TCNT0 = 0x3c; k=k+1; if(k>150) { k=0; PORTA ^= 0x01; } } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main (void) { CLI(); //disable all interrupts port_init(); timer0_init(); MCUCR = 0x00; TIMSK = 0x01; //T0溢出使能 SEI(); //enable interrupts } 6、定时器1测试程序 /***************************************************************************/ /*定时器T1测试程 序 */ /***************************************************************************/ /*********************************包含头文件********************************/ #include <> #include <> /**********************************全局变量*********************************/ int k; /**************************************************************************** 函数功能:端口初始化程序 入口参数: 出口参数: ****************************************************************************/ void port_init (void) { DDRE|=1<<2; PORTE|=1<<2; DDRA=0XFF; PORTA=0XFF; } /**************************************************************************** 函数功能:定时器初始化程序 入口参数: 出口参数: ****************************************************************************/ void timer1_init(void) { TCCR1B = 0x00; //stop,关掉 TCNT1H = 0xFF; //setup 设置高4位初值 TCNT1L = 0x3D; //设置低四位初值 OCR1AH = 0x00; OCR1AL = 0xC3; OCR1BH = 0x00; OCR1BL = 0xC3; OCR1CH = 0x00; OCR1CL = 0xC3; ICR1H = 0x00; ICR1L = 0xC3; TCCR1A = 0x00; TCCR1B = 0x05; //start Timer 1024 } /**************************************************************************** 函数功能:定时中断服务程序 入口参数: 出口参数: ****************************************************************************/ #pragma interrupt_handler timer1_ovf_isr:15 void timer1_ovf_isr(void) { TCNT1H = 0xFF; //reload counter high value TCNT1L = 0x3D; //reload counter low value k=k+1; if(k>40) { k=0; PORTA ^= 0x01; } } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main (void) { CLI(); //disable all interrupts port_init(); timer1_init(); MCUCR = 0x00; TIMSK = 0x04; //T0溢出使能 SEI(); //enable interrupts } 7、定时器1测试程序之二 /***************************************************************************/ /*定时器T1测试程 序 */ /*定时时间为1秒 */ /***************************************************************************/ /*********************************包含头文件********************************/ #include <> #include <> /**********************************全局变量*********************************/ int countnum; /**************************************************************************** 函数功能:端口初始化程序 入口参数: 出口参数: ****************************************************************************/ void port_init (void) { DDRE|=1<<2; PORTE|=1<<2; DDRA=0XFF; PORTA=0XFF; } /**************************************************************************** 函数功能:定时器初始化程序 入口参数: 出口参数: ****************************************************************************/ void timer1_init(void) { TCCR1B = 0x00; //stop TCNT1H = 0x8F; //setup TCNT1L = 0x81; OCR1AH = 0x70; OCR1AL = 0x7F; OCR1BH = 0x70; OCR1BL = 0x7F; OCR1CH = 0x70; OCR1CL = 0x7F; ICR1H = 0x70; ICR1L = 0x7F; TCCR1A = 0x00; TCCR1B = 0x04; //start Timer } /**************************************************************************** 函数功能:定时中断服务程序 入口参数: 出口参数: ****************************************************************************/ #pragma interrupt_handler timer1_ovf_isr:15 void timer1_ovf_isr(void) { TCNT1H = 0x8F; //reload counter high value TCNT1L = 0x81; //reload counter low value countnum++; if(countnum==256) countnum=0; } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main (void) { CLI(); //disable all interrupts port_init(); timer1_init(); TIMSK = 0x04; //T0溢出使能 SEI(); //enable interrupts while(1) { PORTA=countnum; } } 8、串口通信(USART0) /***************************************************************************/ /*串口0测试程 序 */ /*目标器件:ATmega128 */ /*晶振:RC 8MHZ */ /*编译环境:ICCAVR */ /*时间:2010年3月14日 */ */ /***************************************************************************/ /*********************************包含头文件********************************/ #include<> #include<> /***********************************宏定义**********************************/ #define fosc 8000000 //晶振8MHZ #define baud 2400 //波特率 /**************************************************************************** 函数功能:uart0初始化程序 入口参数: 出口参数: ****************************************************************************/ void uart0_init(void) { UCSR0B = 0x00; //关闭UART00 UCSR0A = 0x00; //不使用倍速发送(异步) UCSR0C =(1< UCSR0B =(1< ****************************************************************************/ void putchar0(unsigned char c) { while (!(UCSR0A&(1< ****************************************************************************/ unsigned char getchar0(void) { while(!(UCSR0A& (1< ****************************************************************************/ void puts0(char *s) { while (*s) { putchar0(*s); s++; } putchar0(0x0a);//回车换行 //putchar0(0x0d); } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main(void) { unsigned char i; uart0_init();//UART0初始化 puts0(\"HELLO!\"); while(1) { puts0(\"test ok!\"); } } 9、串口通信(USART1) /***************************************************************************/ /*串口1测试程 序 */ /*目标器件:ATmega128 */ /*晶振:RC 8MHZ */ /*选用的波特率:9600(也可以另外设定),改了波特率后需要将电源拔了再插上方可使用*/ /*编译环境: ICCAVR */ */ /*时间:2010年1月14 日 */ /***************************************************************************/ /*********************************包含头文件********************************/ #include<> #include<> /***********************************宏定义**********************************/ #define fosc 8000000 //晶振8MHZ #define baud 9600 //波特率 /**************************************************************************** 函数功能:uart1初始化程序 入口参数: 出口参数: ****************************************************************************/ void uart1_init(void) //USART1初始化 { UCSR1B = 0x00; //关闭USART1 UCSR1A = 0x00; //不适使用倍速发送 UCSR1C = (1< UCSR1B =(1< 入口参数:c 出口参数: ****************************************************************************/ void putchar1(unsigned char c)//串口1发送字符 { while (!(UCSR1A&(1< ****************************************************************************/ unsigned char getchar1(void) //串口1接回收数据 { while(!(UCSR1A& (1< /**************************************************************************** 函数功能:uart1发送字符串数据 入口参数:*s 出口参数: ****************************************************************************/ void puts1(char *s) { while (*s) { putchar1(*s); s++; } putchar1(0x0a);//回车换行 putchar1(0x0d); } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main(void) { unsigned char i; uart1_init(); puts1(\"HELLO!\"); while(1) { puts1(\"test ok!\"); } } 需要注意的是: 1、要保证串口通信的成功,PC机和单片机必须设置成一样的波特率,这样才能够保证串口通信的成功。 2、上面提到的串口指的是九针的串口,它的几个相应的管脚定义如下: 2 接受数据(RXD) 3 发出数据(TXD) 5 信号地线(SG) 下面是引脚图 10、ATMEGA128 SPI驱动 ATMEGA128单片机SPI通信驱动程序 /************************************************ 文件: 用途:SPI驱动 /************************************************************************* ** 函数名称: spi_init(void) ** 功能描述: SPI初始化 ** 输 入: ** 输出 : ** 全局变量: 无 ** 调用模块: ** 说明: ** 注意: **************************************************************************/ void spi_init(void) { DDRB |= (1< ** 输 入: Data 需要通过SPI传输的数据 ** 输出 : ** 全局变量: 无 ** 调用模块: ** 说明: ** 注意: **************************************************************************/ void SPI_MasterTransmit(char Data) { /* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */ while(!(SPSR & (1< #define uint unsigned int #define uchar unsigned char void delay_ms(uint n) {uint i=0,j; while(i void pwm0_init(void) {DDRB=0X10; TCCR0=0X00; OCR0=0X7F;//8位的定时计数器的初值设定为0x7f TCNT0=0; //计数器 TCCR0=0X6A;//设置为快速pwm模式,采取8分频 } void main(void) {uchar wide; char temp; pwm0_init(); while(1) {delay_ms(50); if(++wide==255) {wide=0; } OCR0=wide; } } 定时器1数码管显示(1s) 文件 /*时间误差:秒每秒*/ #define SS 0 #define SCK 1 #define MOSI 2 #define MISO 3 #define SS_H() PORTB|=(1< void port_init (void) { DDRA=0XFF; PORTA=0XFF; } const unsigned char table[]={0x3F,0x06,0x5B,0x4F,0x66, //0,1,2,3,4 0x6D,0x7D,0x07,0x7F,0x6F, //5,6,7,8,9 0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}; //a,b,c,d,e,f volatile unsigned char led_buffer[4]; void delay_1us(void) //1us延时函数 { asm(\"nop\"); } void delay_nus(unsigned int n) { unsigned int i=0; for (i=0;i unsigned int i; for (i=0;i<1140;i++); } void delay_nms(unsigned int n) { unsigned int i=0; for (i=0;i DDRB |= (1< void SPI_MasterTransmit(char Data) { /* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */ while(!(SPSR & (1< DDRC |= (1< led_buffer[0]=16; //初始化数码管段码 led_buffer[1]=16; led_buffer[2]=16; led_buffer[3]=16; } /*HC595完成传送数据*/ void HC_595_OUT(unsigned char data) { SS_L(); SPI_MasterTransmit(data); SS_H(); } void leddis_update(void) { /*最低位数码管,第四个数码管*/ if(point==0) HC_595_OUT(table[led_buffer[3]]|(1< if(point==1) HC_595_OUT(table[led_buffer[2]]|(1< if(point==2) HC_595_OUT(table[led_buffer[1]]|(1< /*最高位数码管,第一个数码管*/ if(point==3) HC_595_OUT(table[led_buffer[0]]|(1< void display_led(unsigned int data) { if(data>9999) { HC_595_OUT(0xFF); //当计数大于9999时,四个数码管同时输出8 PORTB|=((1<<4)|(1<<5)|(1<<6)|(1<<7)); } else if(data>999) { led_buffer[0]=data/1000; led_buffer[1]=(data%1000)/100; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else if(data>99) { led_buffer[0]=16; //关闭最高位的那个数码管 led_buffer[1]=(data%1000)/100; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else if(data>9) { led_buffer[0]=16; led_buffer[1]=16; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else { led_buffer[0]=16; led_buffer[1]=16; led_buffer[2]=16; led_buffer[3]=data%10; leddis_update(); } } void init_devices(void) { CLI(); //disable all interrupts port_init(); //端口初始化 HC_595_init(); //595初始化 timer1_init(); //定时器1初始化 //TIMSK = 0x04; //定时器1中断溢出使能 //或者写成TIMSK|=(1< /**********************************全局变量*********************************/ int k; volatile unsigned int cnt; /**************************************************************************** 函数功能:定时器初始化程序 入口参数: 出口参数: ****************************************************************************/ void timer1_init(void) { TCCR1B = 0x00; //stop TCNT1H = 0xFF; //setup 1s TCNT1L = 0x3D; //(12*16+2)*40*1024/8000000= OCR1AH = 0x00; OCR1AL = 0xC3; OCR1BH = 0x00; OCR1BL = 0xC3; OCR1CH = 0x00; OCR1CL = 0xC3; ICR1H = 0x00; ICR1L = 0xC3; TCCR1A = 0x00; TCCR1B = 0x05; //start Timer 1024 DDRE|=1<<2; PORTE|=1<<2; } /**************************************************************************** 函数功能:定时中断服务程序 入口参数: 出口参数: ****************************************************************************/ #pragma interrupt_handler timer1_ovf_isr:15 void timer1_ovf_isr(void) { TCNT1H = 0xFF; //reload counter high value TCNT1L = 0x3D; //reload counter low value k=k+1; if(k>40) { k=0; PORTA ^= 0x01; cnt++; if(cnt==10000) cnt=0; } } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main (void) { CLI(); //disable all interrupts init_devices(); MCUCR = 0x00; TIMSK = 0x04; //T0溢出使能 SEI(); //enable interrupts while(1) { display_led(cnt); } } 定时器1:定时计数(1s) 文件: /*********************************包含头文件********************************/ #include <> #include <> #include \"\" /**********************************全局变量*********************************/ int k; volatile unsigned int cnt; unsigned char fenpin[]={0x01,0x02,0x03,0x04,0x05}; //分频系数分别为:1,8,,256,1024; /**************************************************************************** 函数功能:定时器初始化程序 入口参数: 出口参数: ****************************************************************************/ void timer1_init(void) { TCCR1B = 0x00; //stop TCNT1H = 0xF0; //setup 1s TCNT1L = 0xBE; //(16*16*15+4*16)*1024/8000000*2= TCCR1A = 0x00; TCCR1B = fenpin[4]; //start Timer 1024 DDRE|=1<<2; PORTE|=1<<2; } /**************************************************************************** 函数功能:定时中断服务程序 入口参数: 出口参数: ****************************************************************************/ #pragma interrupt_handler timer1_ovf_isr:15 void timer1_ovf_isr(void) { TCNT1H = 0xF0; //reload counter high value TCNT1L = 0xBE; //reload counter low value cnt++; if(cnt==20000) cnt=0; } /**************************************************************************** 函数功能:主程序 入口参数: 出口参数: ****************************************************************************/ void main (void) { CLI(); //disable all interrupts init_devices(); MCUCR = 0x00; TIMSK = 0x04; //T1溢出使能 SEI(); //enable interrupts while(1) { display_led(cnt/2); } } 文件: /*时间误差:秒每秒*/ #define SS 0 #define SCK 1 #define MOSI 2 #define MISO 3 #define SS_H() PORTB|=(1< //开第一个数码管的位选 //关第一个数码管的位选 #define OE 7 #define point 4 #define dp 7 #include <> #include <> void port_init (void) { DDRA=0XFF; PORTA=0XFF; } const unsigned char table[]={0x3F,0x06,0x5B,0x4F,0x66, //0,1,2,3,4 0x6D,0x7D,0x07,0x7F,0x6F, //5,6,7,8,9 0x77,0x7C,0x39,0x5E,0x79,0x71,0x00}; //a,b,c,d,e,f volatile unsigned char led_buffer[4]; void delay_1us(void) //1us延时函数 { asm(\"nop\"); } void delay_nus(unsigned int n) //N us延时函数 { unsigned int i=0; for (i=0;i unsigned int i; for (i=0;i<1140;i++); } void delay_nms(unsigned int n) //N ms延时函数 { unsigned int i=0; for (i=0;i DDRB |= (1< void SPI_MasterTransmit(char Data) { /* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */ while(!(SPSR & (1< DDRC |= (1< led_buffer[0]=16; //初始化数码管段码 led_buffer[1]=16; led_buffer[2]=16; led_buffer[3]=16; } /*HC595完成传送数据*/ void HC_595_OUT(unsigned char data) { SS_L(); SPI_MasterTransmit(data); SS_H(); } void leddis_update(void) { /*最低位数码管,第四个数码管*/ if(point==0) HC_595_OUT(table[led_buffer[3]]|(1< delay_nus(60); led0_dis(); if(point==1) HC_595_OUT(table[led_buffer[2]]|(1< if(point==2) HC_595_OUT(table[led_buffer[1]]|(1< /*最高位数码管,第一个数码管*/ if(point==3) HC_595_OUT(table[led_buffer[0]]|(1< } void display_led(unsigned int data) { if(data>9999) { HC_595_OUT(0xFF); //当计数大于9999时,四个数码管同时输出8 PORTB|=((1<<4)|(1<<5)|(1<<6)|(1<<7)); } else if(data>999) { led_buffer[0]=data/1000; led_buffer[1]=(data%1000)/100; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else if(data>99) { led_buffer[0]=16; //关闭最高位的那个数码管 led_buffer[1]=(data%1000)/100; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else if(data>9) { led_buffer[0]=16; led_buffer[1]=16; led_buffer[2]=(data%100)/10; led_buffer[3]=data%10; leddis_update(); } else { led_buffer[0]=16; led_buffer[1]=16; led_buffer[2]=16; led_buffer[3]=data%10; leddis_update(); } } void init_devices(void) { // CLI(); //disable all interrupts port_init(); //端口初始化 HC_595_init(); //595初始化 timer1_init(); //定时器1初始化 //TIMSK = 0x04; //定时器1中断溢出使能 //或者写成TIMSK|=(1< 外部中断0-3 /*============================================================ 外部中断0-3点亮发光二极管 必须注意的是:假如使用的是下降沿触发,就必须保证在未按下键盘的情况下,相 应的外部中断的管脚必须是高电平,按下键盘时产生下降沿,触发外部中断。其他 的情况以此类推。 =============================================================*/ #include <> #include <> volatile unsigned char cnt=255; void initialize(void); #pragma interrupt_handler outinterrupt0:2//外部中断0 void outinterrupt0() { cnt=cnt-1; if(cnt==0) cnt=255; } #pragma interrupt_handler outinterrupt1:3//外部中断1 void outinterrupt1() { cnt=cnt-1; if(cnt==0) cnt=255; } #pragma interrupt_handler outinterrupt2:4//外部中断2 void outinterrupt2() { cnt=cnt-1; if(cnt==0) cnt=255; } #pragma interrupt_handler outinterrupt3:5//外部中断3 void outinterrupt3() { cnt=cnt-1; if(cnt==0) cnt=255; } int main(void) { initialize(); DDRD=0xf0;//将INT0-INT3设置为输入 while(1) { PORTA=cnt; } } void initialize(void) { EIMSK=0x0f; 0-3 使用外部中断 // EICRA=0xaa; // 下降沿中断请求(异步) SEI(); // SREG的最高位置1 DDRE|=1<<2; //发光二极管片选 PORTE|=1<<2; DDRA=0XFF; } 定时器3 pwm输出 /*====================================================== 使用定时器3,OCR3A,OCR3B,OCR3C三个管脚同时输出PWM波形 在快速PWM的模式下,top=0x03ff=1023 OCRnX在top时刻更新 频率=8000000/8/1023= =======================================================*/ #include <> int main () { unsigned int i,a=0,c=0; unsigned char b=0; TCCR3A=0xff; //通道A,B,C均设置为比较输出模式 TCCR3B=0x0A; //采用10位快速PWM模式,top值为0X03FF,决定pwm频率; TCNT3=0X0000; //设置定时器的初始值 TIMSK=0X00; ETIMSK=0X00; DDRE=0xff; while(1) { OCR3A=512; //决定OCR3A的占空比 OCR3B=256; //决定OC3B的占空比 OCR3C=OCR3C+1; //决定OC3C的占空比 c++; OCR3C=c; if(c>=0x03f0) {c=0;}; i=500; while(i--); } } 因篇幅问题不能全部显示,请点此查看更多更全内容
Copyright © 2019- jqkq.cn 版权所有 赣ICP备2024042794号-4
违法及侵权请联系:TEL:199 1889 7713 E-MAIL:2724546146@qq.com
本站由北京市万商天勤律师事务所王兴未律师提供法律服务