简易AVR单片机教程.docx
《简易AVR单片机教程.docx》由会员分享,可在线阅读,更多相关《简易AVR单片机教程.docx(69页珍藏版)》请在冰豆网上搜索。
简易AVR单片机教程
简易单片机教程
ICCAVR的使用
参考程序代码
1模拟比较器
#include
#include
voidmain()
{
unsignedcharmid;
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:
CWB
Data:
2010-05-05
--------------------------------*/
#include
voiddelay_ms(intms)
{
intm,n;
for(m=0;m<=ms;m++)
for(n=0;n<=450;n++);
}
voidmain()
{
inti,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=(j<<1);
}
for(i=0;i<=6;i++)
{
PORTA=j;
PORTB=j;
PORTD=j;
delay_ms(600);
j=(j>>1);
}
}
}
3、定时计数器TC2
#include
#pragmainterrupt_handlerMyCounter:
20
staticintiCounter=0;
voidMyCounter(void)
{
if(iCounter<=10)
{
//PORTA^=0xFF;//~PINA;//0xFF;//
iCounter++;
//iCounter=0;
}
elseiCounter=0;
}
voidmain(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");
//总中断开放SREG|=0x80;
while
(1)
{
//inti,j;
//for(i=0;i<1000;i++)
//for(j=0;j<400;j++);
if(iCounter==8)PORTA^=0xFF;
};
}
4、计数器TC0
#include
#pragmainterrupt_handlerMyCounter:
20
staticintiCounter=0;
voidMyCounter(void)
{
if(iCounter<=10)
{
//PORTA^=0xFF;//~PINA;//0xFF;//
iCounter++;
//iCounter=0;
}
elseiCounter=0;
}
voidmain(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)
{
inti,j;
//for(i=0;i<1000;i++)
//for(j=0;j<400;j++);
if(iCounter==8)
{PORTA^=0xFF;
for(i=0;i<1000;i++)
for(j=0;j<400;j++);
}
};
}
5、EEPROM
/*访问单片机资源EEPROM*/
#include
#definesei()SREG|=0X80
#definecli()SREG&=0X7F
//EEPROM控制寄存器位定义
#defineEERE0//READ
#defineEEWE1//WRITE
#defineEEMWE2//总写入
#defineWWRIE3//中断
/*端口初始化*/
void_init(void)
{
DDRA=0XFF;
PORTA=0XFF;}
/*EEPROM读程序*/
charEEPROM_R(unsignedintEEAdd)
{
while(EECR&(1<EEAR=EEAdd;//设置读入地址
EECR|=(1<returnEEDR;}
/*EEPROM写程序*/
charEEPROM_W(unsignedintEEAdd,unsignedcharEEData)
{
while(EECR&(1<EEAR=EEAdd;//设置写入地址
EEDR=EEData;//设置写入数据
EECR|=(1<EECR|=(1<}
voidmain()
{
_init();
cli();//关中断
EEPROM_W(0X100,0X07);//将数据写入EEPROM中的0x0100单元
PORTA=EEPROM_R(0X0100);//读取0x0100单元的数据,送显
sei();//开中断
/***********************
开中断关中断的作用?
?
*****************************/
while
(1);
}
6、计数器测频率
#include
/*******************
程序还有问题要解决
**************************/
voidmain()
{
DDRB=0x08;
PORTB=0x00;//PB3(OC0)CONFIGoutput
TCCR0=0x1B;//64分频pwm比较匹配发生oc0触发
TCNT0=0x00;
OCR0=0x80;//RECTWAVE
ASSR=0x00;//同步方式
///T/C2目的定时1MS
TCCR2=0x0B;//32fenpinCTC与输出引脚断开
TCNT2=0x00;//从零开始记数
OCR2=0x7D;//0b01111101~~125
TCCR1A=0x00;
TCCR1B=0x06;//时钟外部T1引酵下降驱动一般模式
TCNT1H=0x00;
TCNT1L=0x00;//从零开始记数
ICR1H=0x00;//似乎没用到输入捕获寄存器?
?
OCR1AH=0x00;
OCR1AL=0x00;
OCR1BH=0x00;
OCR1BL=0x00;//都为0TCNT1中也为0比较匹配貌似在这种情况不发生
TIMSK=0x80;
SREG|=0x80;//t/c2比较匹配中断开放全局中断开放
}
7、串口中断int
//Target:
M16
//Crystal:
8.0000Mhz
//AVR单片机atmega16串口中断接收和发送程序。
接收到字符后再发送出去
#include
#include
unsignedcharcom_in_buf[1];
voidport_init(void)
{
PORTA=0xFF;
DDRA=0xFF;
PORTB=0x00;
DDRB=0x00;
PORTC=0x00;
DDRC=0x00;
PORTD=0x00;
DDRD=0x00;
}
//UART0initialize
//desiredbaudrate:
9600
//actual:
baudrate:
9615(0.2%)
//charsize:
8bit
//parity:
Disabled
voiduart0_init(void)
{
UCSRB=0x00;//disablewhilesettingbaudrate
UCSRA=0x00;
UCSRC=BIT(URSEL)|0x06;
UBRRL=0x33;//setbaudratelo
UBRRH=0x00;//setbaudratehi
UCSRB=0x98;
}
voidsend_data(unsignedcharback)
{
while(!
(UCSRA&(1<UDR=back;
}
#pragmainterrupt_handleruart0_rx_isr:
12
voiduart0_rx_isr(void)
{
//uarthasreceivedacharacterinUDR
com_in_buf[0]=UDR;
send_data(com_in_buf[0]);
}
//callthisroutinetoinitializeallperipherals
voidinit_devices(void)
{
//stoperrantinterruptsuntilsetup
CLI();//disableallinterrupts
port_init();
uart0_init();
MCUCR=0x00;
GICR=0x00;
TIMSK=0x00;//timerinterruptsources
SEI();//re-enableinterrupts
//allperipheralsarenowinitialized
}
voidmain(void)
{
charj;
init_devices();
while
(1)
{
for(j=1;j<100;j++)
;
}
}
8、中断
#include
//#include
voiddelay_ms(ms)
{
inti;
for(i=0;i<=ms;i++)
for(i=0;i<=10;i++);
}
intx;
voidmain()
{
DDRA=0xFF;
PORTA=0xF0;
//GICR=0x40;//INT0中断使能//通用中断控制寄存器
//MCUCR=0x07;//上升沿触发//MCU控制寄存器
//MCUCSR=0x00;//MCUCSR//MCU控制和状态寄存器
//GIFR=0x40;//通用中断标志寄存器
//SREG|=0x80;//全局使能,状态寄存器#asm("sei")
while
(1)
{
PORTA=~(PORTA&0x04);
delay_ms(50);
}
}
//#pragmainterrupt_handlerint0_isr:
2
//voidint0_isr(void)
//{
//x++;
//}
9、键盘扫描
#include
voiddelay_ms(ms)
{
inti;
for(i=0;i<=ms;i++)
for(i=0;i<=400;i++);
}
charScan()
{
chartem_key;
DDRB=0X0F;
PORTB=0B11110000;
if(PINB==0XF0)return(0XFF);
if(PINB&0X08==0)tem_key=0;
elseif(PINB&0X10==0)tem_key=1;
elseif(PINB&0X20==0)tem_key=2;
elseif(PINB&0X30==0)tem_key=3;
DDRB=0B11110000;//反转
PORTB=0X0F;
delay_ms(5);
If(PINB&0X01==0)tem_key=tem_key+0;//获取按下键的行编码
elseif(PINB&0X02==0)tem_key=tem_key+4;
elseif(PINB&0X03==0)tem_key=tem_key+8;
elseif(PINB&0X04==0)tem_key=tem_key+12;
return(tem_key);
}
voidmain()
{
Scan();
}
10、八端口液晶程序
#include
#include
#defineucharunsignedchar
#defineuintunsignedint
//#pragmadata:
code
//?
?
constuchartable[]="ILIKEAVR!
";
constuchartable2[]="ILIKEPIC!
";
voiddelay(uintms)
{
uinti,j;
for(i=0;ifor(j=0;j<1141;j++);
}
voidwriteCom(ucharcom)
{
PORTD&=~BIT(4);//RS拉低-为命令选择
PORTD&=~BIT(5);//R/W拉低-选择写
PORTB=com;//写入命令
PORTD|=BIT(6);//E高电平-使能
delay
(1);
PORTD&=~BIT(6);//使能关闭
}
voidwriteData(uchardata)
{
PORTD|=BIT(4);//RS位拉高为数据选择
PORTD&=~BIT(5);//R/W拉低-选择写
PORTB=data;//写入数据
PORTD|=BIT(6);//E高电平-使能
delay
(1);
PORTD&=~BIT(6);//使能关闭
}
voidmain()
{
uchari;
DDRB=0xFF;
DDRD|=BIT(4)|BIT(5)|BIT(6);//456输出分别为RSRWE的控制端
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);
for(i=0;i<12;i++)
{
writeData(table[i]);
delay(5);
}
writeCom(0x80+0x40);//设置数据地址指针第二行第一列
delay(5);
for(i=0;i<13;i++)
{
writeData(table2[i]);
delay(5);
}
}
11、SPI_AD5300
#include
#include
delay(unsignedinttemp)
{
inti,j;
for(i=0;ifor(j=0;j<1141;j++);
}
voidSPI_Init()
{
DDRB|=0XA0;
DDRA|=BIT(PA1);
SPCR=0X57;
}
voidAD5300(unsignedcharDAdata)
{
unsignedchartemp1=0,temp2=0,status;
temp1|=DAdata<<4;//11011001
temp2|=DAdata>>4;
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);
}
voidmain()
{
SPI_Init();
AD5300;
}
12、TC0_PWM
#include
#pragmainterrupt_handleriFunction:
20
voidiFunction()
{
PORTA=0X11;
/*************************
中断没有进入程序有问题待解决
***********************/
}
voidmain()
{
DDRA=0xFF;
PORTA=0xFF;
DDRB=0xFF;
PORTB=0xFF;
TCCR0=0x64;//PWM256分频正向PWM——T/C0向上计数过程中比较匹配时清零OC0,T/C0向下计数过程中比较匹配时置位OC0
//TCNT0/的值没有设定=0x00;/
OCR0=0x80;
//ASSR异步模式状态寄存器只适用于TC0且只有第四位起作用,高四位保留
//TIFR中断标志寄存器未设定//|=0x02;
TIMSK=0x02;//t/c0比较匹配中断开放
SREG|=0x80;//全局中断使能
while
(1)
{}
}
13、TC2
#include
#pragmainterrupt_handlermyCounter:
4
voidmyCounter(void)
{
PORTA=~PINA;
}
voidmain(void)
{
DDRA=0XFF;
PORTA=0XFF;
DDRD=0xFF;//定义PD口为输出
PORTD=0x00;
//比较匹配后oc2触发计数频率256分频CTC模式
TCCR2=0x1E;//CTC模式比较傲匹配发生时触发oc2110--256分频
ASSR=0x08;//外部时钟
TCNT2=0x00;//写入初值+
OCR2=0x80;//比较匹配值为128
TIMSK=0x80;//比较匹配中断开放
SREG|=0x80;
while
(1)
{
}
}
14、TWI_AT24C02
#include
//定义TWI状态
//MT主方发送MR主方接受
#defineSTART0X08
#defineRE_START0X10
#defineMT_SLA_ACK0X18
#defineMT_SLA_NOACK0X20
#defineMT_DATA_ACK0X28
#defineMT_DATA_NOACK0X30
#defineMR_SLA_ACK0X40
#defineMR_SLA_NOACK0X48
#defineMR_DATA_ACK0X50
#defineMR_DATA_NOACK0X58
#defineRD_DEVICE_ADDR0XA1
//前四位固定后三位看连线
#defineWD_DEVICE_ADDR0XA0
/*常用TWI操作(主模式写和读)*/
#defineStart()(TWCR=(1<#defineStoop()(TWCR=(1<#defineWait(){while(!
(TWCR&(1<#defineTestAck()(TWSR&0XF8)//观察返回状态
#defineSetAck()(TWCR|=(1<#defineSetNoAck()(TWCR&=~(TWEA))//做出NoA