简易AVR单片机教程.docx

上传人:小飞机 文档编号:1674537 上传时间:2022-12-13 格式:DOCX 页数:47 大小:2.72MB
返回 下载 相关 举报
简易AVR单片机教程.docx_第1页
第1页 / 共47页
简易AVR单片机教程.docx_第2页
第2页 / 共47页
简易AVR单片机教程.docx_第3页
第3页 / 共47页
简易AVR单片机教程.docx_第4页
第4页 / 共47页
简易AVR单片机教程.docx_第5页
第5页 / 共47页
点击查看更多>>
资源描述

《简易AVR单片机教程.docx》由会员分享,可在线阅读,更多相关《简易AVR单片机教程.docx(47页珍藏版)》请在三一办公上搜索。

1、简易单片机教程ICCAVR的使用参考程序代码1模拟比较器#include#includevoid main() unsigned char mid; DDRC=0xFF; PORTC=0xFF; ACSR=0x00; /启动模拟比较器 参考电压接比较器正端 中断屏蔽 触发定时计数器1的捕获关闭 while(1) mid=ACSR&0x20; /读出模拟比较器的输出值 if(mid=0) PORTC|=BIT(0); /PC0=1 else PORTC&=BIT(0); /PC0=0 2彩灯(软件例子程序)/*-Function:流水灯Author:CWBData:2010-05-05-*/#i

2、ncludevoid delay_ms(int ms) int m,n; for(m=0;m=ms;m+) for(n=0;n=450;n+);void main() int i,j,k; DDRA=0xFF; DDRB=0xFF; DDRC=0xFF; DDRD=0xFF; PORTA=0x00; PORTB=0x00; PORTC=0x00; PORTD=0x00; while(1) j=0x01;for(i=0;i=6;i+) PORTA=j;PORTB=j;PORTD=j;delay_ms(600);j=(j1);for(i=0;i1); 3、定时计数器TC2#include#prag

3、ma interrupt_handler MyCounter:20static int iCounter=0;void MyCounter(void) if(iCounter=10) /PORTA=0xFF;/PINA;/0xFF;/iCounter+; /iCounter=0; else iCounter=0;void main(void) DDRA=0xFF; PORTA=0x00; /PORTB=0xFF; DDRB=0xFF; TCCR0=0x1B;/PWM相位可调,T/C0与输出引脚断开,CLK/64分频/00011011 TCNT0=0x00;/从0开始计数 OCR0=0x3E;/

4、达到63时,比较匹配发生 TIMSK=0x02;/中断屏蔽寄存器T/C0输出匹配中断使能 #asm(sei); /总中断开放 SREG|=0x80; while(1) /int i,j; / for(i=0;i1000;i+) / for(j=0;j400;j+); if (iCounter=8) PORTA=0xFF;4、计数器TC0#include#pragma interrupt_handler MyCounter:20static int iCounter=0;void MyCounter(void) if(iCounter=10) /PORTA=0xFF;/PINA;/0xFF;/i

5、Counter+; /iCounter=0; else iCounter=0;void main(void) DDRA=0xFF; PORTA=0x00; /PORTB=0xFF; DDRB=0xFF; TCCR0=0x1B;/PWM相位可调,T/C0与输出引脚断开,CLK/64分频/00011011 TCNT0=0x00;/从0开始计数 OCR0=0x3E;/达到63时,比较匹配发生 TIMSK=0x02;/中断屏蔽寄存器T/C0输出匹配中断使能 #asm(sei) /* /不明原因,C中嵌入汇编不能用 */ SREG|=0x80; /总中断开放 SREG|=0x80; while(1) i

6、nt i,j; / for(i=0;i1000;i+) / for(j=0;j400;j+); if (iCounter=8) PORTA=0xFF; for(i=0;i1000;i+) for(j=0;j400;j+); ;5、EEPROM/*访问单片机资源EEPROM*/#include#define sei() SREG|=0X80#define cli() SREG&=0X7F/EEPROM控制寄存器位定义#define EERE 0/READ#define EEWE 1/WRITE#define EEMWE 2/总写入#define WWRIE 3/中断/*端口初始化*/void _

7、init(void) DDRA=0XFF; PORTA=0XFF; /*EEPROM读程序*/char EEPROM_R(unsigned int EEAdd) while(EECR&(1EEWE); /写等待 EEAR=EEAdd; /设置读入地址 EECR|=(1EERE); /读命令 return EEDR; /*EEPROM写程序*/char EEPROM_W(unsigned int EEAdd, unsigned char EEData) while(EECR&(1EEWE); /写等待 EEAR=EEAdd; /设置写入地址 EEDR=EEData; /设置写入数据 EECR|=

8、(1EEMWE); /总写入允许 EECR|=(1EEWE); /开始写入 void main() _init(); cli(); /关中断 EEPROM_W(0X100, 0X07); /将数据写入EEPROM中的0x0100单元 PORTA=EEPROM_R(0X0100); /读取0x0100单元的数据,送显 sei(); /开中断/*开中断关中断的作用?*/ while(1);6、计数器测频率#include/*程序还有问题要解决*/void main() DDRB=0x08; PORTB=0x00;/PB3(OC0) CONFIG output TCCR0=0x1B;/64分频 pw

9、m 比较匹配发生oc0触发 TCNT0=0x00; OCR0=0x80;/RECT WAVE ASSR=0x00; /同步方式 /T/C2 目的定时1MS TCCR2=0x0B;/32 fen pin CTC 与输出引脚断开 TCNT2=0x00;/从零开始记数 OCR2=0x7D;/0b0111 1101125 TCCR1A=0x00; TCCR1B=0x06;/时钟 外部T1引酵 下降驱动 一般模式 TCNT1H=0x00; TCNT1L=0x00; /从零开始记数 ICR1H=0x00;/似乎没用到输入捕获寄存器? OCR1AH=0x00; OCR1AL=0x00; OCR1BH=0x0

10、0; OCR1BL=0x00;/都为0 TCNT1中也为0 比较匹配貌似在这种情况不发生 TIMSK=0x80; SREG|=0x80; /t/c2 比较匹配中断开放 全局中断开放 7、串口中断int/ Target : M16 / Crystal: 8.0000Mhz /AVR单片机atmega16串口中断接收和发送程序。接收到字符后再发送出去 #include #include unsigned char com_in_buf1; void port_init(void) PORTA = 0xFF; DDRA = 0xFF; PORTB = 0x00; DDRB = 0x00; PORTC

11、 = 0x00; DDRC = 0x00; PORTD = 0x00; DDRD = 0x00; /UART0 initialize / 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 = 0x33; /set baud rat

12、e lo UBRRH = 0x00; /set baud rate hi UCSRB = 0x98; void send_data(unsigned char back) while( !( UCSRA & (1UDRE) ) ; UDR=back; #pragma interrupt_handler uart0_rx_isr:12 void uart0_rx_isr(void) /uart has received a character in UDR com_in_buf0=UDR; send_data(com_in_buf0); /call this routine to initial

13、ize all peripherals void init_devices(void) /stop errant interrupts until set up CLI(); /disable all interrupts port_init(); uart0_init(); MCUCR = 0x00; GICR = 0x00; TIMSK = 0x00; /timer interrupt sources SEI(); /re-enable interrupts /all peripherals are now initialized void main(void) char j; init_

14、devices(); while(1) for(j=1;j100;j+) ; 8、中断#include/#includevoid delay_ms(ms)int i; for(i=0;i=ms;i+) for(i=0;i=10;i+);int x;void main() DDRA=0xFF; PORTA=0xF0;/ GICR=0x40; /INT0中断使能/通用中断控制寄存器 /MCUCR=0x07; /上升沿触发 /MCU控制寄存器 /MCUCSR=0x00;/MCUCSR/MCU控制和状态寄存器 /GIFR=0x40;/通用中断标志寄存器 /SREG|=0x80;/全局使能,状态寄存器

15、#asm(sei) while(1) PORTA=(PORTA&0x04); delay_ms(50); /#pragma interrupt_handler int0_isr:2/void int0_isr(void)/ /x+;/9、键盘扫描#includevoid delay_ms(ms)int i; for(i=0;i=ms;i+) for(i=0;i=400;i+);char Scan() char tem_key; DDRB=0X0F; PORTB=0B11110000; if(PINB=0XF0) return(0XFF); if(PINB&0X08=0)tem_key=0; e

16、lse if(PINB&0X10=0)tem_key=1; else if(PINB&0X20=0)tem_key=2; else if(PINB&0X30=0)tem_key=3; DDRB=0B11110000;/反转PORTB=0X0F;delay_ms(5);If(PINB&0X01=0)tem_key=tem_key+0; /获取按下键的行编码 else if(PINB&0X02=0)tem_key=tem_key+4; else if(PINB&0X03=0)tem_key=tem_key+8; else if(PINB&0X04=0)tem_key=tem_key+12; ret

17、urn(tem_key);void main() Scan();10、八端口液晶程序#include#include#define uchar unsigned char#define uint unsigned int/#pragma data:code/?const uchar table=I LIKE AVR!;const uchar table2=I LIKE PIC !;void delay(uint ms) uint i,j; for(i=0;ims;i+) for(j=0;j1141;j+);void writeCom(uchar com) PORTD&=BIT(4);/RS 拉

18、低-为命令选择 PORTD&=BIT(5);/R/W拉低-选择写 PORTB=com;/写入命令 PORTD|=BIT(6);/E高电平-使能 delay(1); PORTD&=BIT(6);/使能关闭void writeData(uchar data) PORTD|=BIT(4);/RS位拉高 为数据选择 PORTD&=BIT(5);/R/W拉低-选择写 PORTB=data;/写入数据 PORTD|=BIT(6);/E高电平-使能 delay(1); PORTD&=BIT(6);/使能关闭void main() uchar i; DDRB=0xFF; DDRD|=BIT(4)|BIT(5)

19、|BIT(6);/456输出 分别为 RS RW E的控制端 PORTD&=BIT(6);/使能关闭 writeCom(0X38);/显示模式设置 16x2显示 5x7点阵 8位数据接口 delay(5); writeCom(0X01);/显示清屏 (数据指针 所有显示) delay(5); writeCom(0X0C);/开显示 光标不显示 不闪烁 delay(5); writeCom(0X06);/读或写一个字符后 地址指针加一,且光标加一 若配置s位 则可以出现移屏效果 delay(5); writeCom(0X80+0x00);/设置数据地址指针 第一行 第一列 delay(5); f

20、or(i=0;i12;i+) writeData(tablei); delay(5); writeCom(0x80+0x40);/设置数据地址指针 第二行第一列 delay(5); for(i=0;i13;i+) writeData(table2i); delay(5); 11、SPI_AD5300#include#includedelay(unsigned int temp) int i,j; for(i=0;itemp;i+) for(j=0;j1141;j+);void SPI_Init() DDRB|=0XA0; DDRA|=BIT(PA1); SPCR=0X57;void AD530

21、0(unsigned char DAdata) unsigned char temp1=0,temp2=0,status; temp1|=DAdata4; PORTA&=BIT(PA1); SPSR=0; SPDR=temp2; do status=SPSR; while(!(status&0x80); delay(10); SPSR=0; SPDR=temp1; do status=SPSR; while(!(status&0X80); SPSR=0; delay(10); PORTA|=BIT(PA1); void main() SPI_Init(); AD5300;12、TC0 _ PW

22、M#include#pragma interrupt_handler iFunction:20void iFunction() PORTA=0X11; /* 中断没有进入 程序有问题待解决 */void main() DDRA=0xFF; PORTA=0xFF; DDRB=0xFF; PORTB=0xFF; TCCR0=0x64; /PWM 256分频 正向PWMT/C0向上计数过程中比较匹配时清零OC0,T/C0向下计数过程中比较匹配时置位OC0 /TCNT0/ 的值没有设定=0x00;/ OCR0=0x80; /ASSR异步模式状态寄存器只适用于TC0 且只有第四位起作用,高四位保留 /T

23、IFR中断标志寄存器 未设定/|=0x02; TIMSK=0x02; /t/c0比较匹配中断开放 SREG|=0x80; /全局中断使能 while(1) 13、TC2#include#pragma interrupt_handler myCounter:4void myCounter(void) PORTA=PINA; void main(void) DDRA=0XFF; PORTA=0XFF; DDRD=0xFF; /定义PD口为输出 PORTD=0x00; /比较匹配后oc2触发 计数频率256分频 CTC模式 TCCR2=0x1E;/CTC模式 比较傲匹配发生时触发oc2 110-25

24、6分频 ASSR=0x08;/外部时钟 TCNT2=0x00;/写入初值+ OCR2=0x80;/比较匹配值为128 TIMSK=0x80;/比较匹配中断开放 SREG|=0x80; while(1) 14、TWI_AT24C02#include/定义TWI状态/MT 主方发送 MR 主方接受#define START 0X08#define RE_START 0X10#define MT_SLA_ACK 0X18#define MT_SLA_NOACK 0X20#define MT_DATA_ACK 0X28#define MT_DATA_NOACK 0X30#define MR_SLA_A

25、CK 0X40#define MR_SLA_NOACK 0X48#define MR_DATA_ACK 0X50#define MR_DATA_NOACK 0X58#define RD_DEVICE_ADDR 0XA1 /前四位固定 后三位看连线#define WD_DEVICE_ADDR 0XA0/*常用TWI操作(主模式写和读)*/#define Start() (TWCR=(1TWINT)|(1TWSTA)|(1TWEN) /启动TWI#define Stoop() (TWCR=(1TWINT)|(1TWSTO)|(1TWEN) /停止TWI#define Wait() while(!(

26、TWCR&(1TWINT); /等待中断发生#define TestAck() (TWSR&0XF8) /观察返回状态#define SetAck() (TWCR|=(1TWEA) /做出ACK应答#define SetNoAck() (TWCR&=(TWEA) /做出NoAck应答#define Twi() (TWCR=(1TWINT|(1TWEN) /启动I2C#define Write8Bit(x) TWDR=(x);TWCR=(1TWINT)|(1TWEN);/写数据到.delay_ms(unsigned int temp) int i,j; for(i=0;itemp;i+) for

27、(j=0;j1141;j+);unsigned char TWI_Write(unsigned char Wdata,unsigned char RegAddress) Start();/TWI启动 Wait(); if(TestAck()!=START) return 1;/ACK Write8Bit(WD_DEVICE_ADDR); /写TWI从器件地址和写方式 Wait(); if(TestAck()!=MT_SLA_ACK) return 1; /ACK Write8Bit(RegAddress); /写器件相应寄存器地址 Wait(); if(TestAck()!=MT_DATA_A

28、CK) return 1; /ACK Write8Bit(Wdata); /写数据到相应寄存器 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; /ACK Stop(); /TWI停止 delay_ms(10); return 0;unsigned char TWI_Read(unsigned RegAddress) unsigned char temp; Start();/TWI启动 Wait();/ if(TestAck()!=START() return 1; /ACK Write8Bit(WD_DEVICE_ADDR); /写TWI从器件地址和写

29、方式 Wait(); if(TestAck()!=MT_SLA_ACK) return 1; /ACK Write8Bit(RegAddress); /写器件相应寄存器地址 Wait(); / if(TestAck()!=MT_DATA_ACK) return 1; /ACK Write8Bit(Wdata); /写数据到相应寄存器 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; /ACK Write8Bit(Wdata); /写数据到相应寄存器 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; /ACK Wri

30、te8Bit(Wdata); /写数据到相应寄存器 Wait(); if(TestAck()!=MT_DATA_ACK) return 1; /ACK Write8Bit(Wdata); /写数据到相应寄存器 Wait(); 15、UART#include/*串口以查询方式接受并发送数据*/void Uart_Init() UCSRA=0X02; /倍速 UCSRB=0X18;/允许接受和发送 UCSRC=0X86;/8位数据 UBRRH=0X00;/ UBRRL=12; /9600/*数据发送查询方式*/void Uart_Transmit(unsigned char cData) whil

31、e(!(UCSRA&(1UDRE);/等待缓冲区为空 UDR=cData;/发送数据unsigned char Uart_Receive() while(!(UCSRA&(1RXC)/等待接受数据 return UDR;/获取并返回数据/*主函数*/void main() unsigned char temp; DDRD=0X02; PORTD=0XFF; Uart_Init(); while(1) temp=Uart_Receive(); Uart_Transmit(temp); 16、看门狗#include/*看门狗定时器的关断,必须遵循下列顺序:(1)在同一个操作中,将WDTOE和WDE

32、置“1”;(2)在随后的4个时钟周期内,清“0”WDE位。*/void main() WDTCR=0x0B; /启动看门狗,并设置溢出时间为120ms 0.13s? while(1) #asm(wdr) /汇编复位看门狗 if(expression) /当条件满足时,禁用看门狗 WDTCR=0x18; /将WDTOE和WDE同时置1WDTCR=0x00; /清0WDE看门狗停止工作/.其他代码 17、阿莫实验板 DS1302时钟实验#include #include #include main.h#include DS1302.h/初始化SPI接口void init_SPI(void) SPC

33、R = (1SPE)|(1MSTR)|(1DORD)|(1SPR0); / 使能SPI接口,主机模式,LSB低位在先,模式0,16分频,SPI时钟约460KHz/*-Single_SPI : 使用SPI接口读写数据到DS1302 输入参数:command:命令选择;wdata:写入的数据;返回值rdata:读回的数据; (SPI的收发是同时进行的)-*/unsigned char Single_SPI(unsigned char command,unsigned char wdata)unsigned char rdata; EnDS1302;/ 使能LCD _delay_us(10); SP

34、DR = command; / 传送命令到SPI寄存器 loop_until_bit_is_set(SPSR,SPIF);/ 等待数据传送完? _delay_us(10); SPDR = wdata; / 传送数据到SPI寄存器 loop_until_bit_is_set(SPSR,SPIF);/ 等待数据传送完? rdata=SPDR;/ 读取数据 DiDS1302;/ 关断LCD SPI通讯 _delay_us(10); return rdata;/*-Burst_SPI : 使用SPI接口读写一批数据到DS1302 输入参数:CMD:选择Clock/RAM,选择读写lenth:数据长度p

35、wdata:写入数据的缓冲区;prdata:读回数据的缓冲区; (SPI的收发是同时进行的)读CLOCK的数据从SECOND寄存器开始,到CONTROL寄存器,最大8字节写CLOCK的数据必须一次写完8个字节读写RAM的数据从 RAM0地址开始,到RAM30地址,最大31字节-*/void Burst_SPI(unsigned char CMD,unsigned char len,unsigned char *pwdata,unsigned char *prdata) EnDS1302;/ 使能SPI通讯 _delay_us(10);SPDR=CMD;/ 传送命令到SPI寄存器 loop_until_bit_is_set(SPSR,SPIF);/ 等待数据传送完? _delay_us(10); while (len-) SPDR = *pwdata+; / 传送数据到SPI寄存器 loop_until_bit_is_set(SPSR,SPIF);/ 等待数据传送完? *prdata+=SPDR;/ 读取数据;

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 生活休闲 > 在线阅读


备案号:宁ICP备20000045号-2

经营许可证:宁B2-20210002

宁公网安备 64010402000987号