avr单片机程序.doc
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
* 文件名:闪烁灯.c
* 杜邦线接法:用单条杜邦线把PD.0和J38的1端相连接。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define LED1 PORTD|=~0XFE //LED=1 LED不亮
#define LED0 PORTD&=0XFE //LED=0 LED发光
int main(void)
{
DDRD = 0x01; //PD0定义为输出,PD的其他端口为输入。
while(1)
{
LED1;
_delay_ms(500);
LED0;
_delay_ms(500);
}
}
* 文件名:闪烁灯2.c
* 创建人:东流,2012年2月10日
* 版本号:1.0
* 杜邦线接法:用8针杜邦线把PD和J38的1--8连接(PD0对应J38的1端)。
用杜邦线把PB0对应J38的9端。
用杜邦线把PB1对应J38的10端。
用杜邦线把PB2对应J38的11端。
用杜邦线把PB3对应J38的12端。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
int main(void)
{
DDRD = 0xff;
DDRB = 0x0f;
while(1)
{
/*北面的三个LED亮*/
PORTD = 0xf8;
PORTB = 0xff;
_delay_ms(300);
/*东面的三个LED亮*/
PORTD = 0xc7;
PORTB = 0xff;
_delay_ms(300);
/*南面的三个LED亮*/
PORTD = 0x3f;
PORTB = 0xfe;
_delay_ms(300);
/*西面的三个LED亮*/
PORTD = 0xff;
PORTB = 0xf1;
_delay_ms(300);
/*北面的两个LED亮,中间一个不亮*/
PORTD = 0xfa;
PORTB = 0xff;
_delay_ms(300);
/*东面的两个LED亮,中间一个不亮*/
PORTD = 0xd7;
PORTB = 0xff;
_delay_ms(300);
/*南面的两个LED亮,中间一个不亮*/
PORTD = 0xbf;
PORTB = 0xfe;
_delay_ms(300);
/*西面的两个LED亮,中间一个不亮*/
PORTD = 0xff;
PORTB = 0xf5;
_delay_ms(300);
/*12个LED全亮*/
PORTD = 0x00;
PORTB = 0xf0;
_delay_ms(200);
/*12个LED全灭*/
PORTD = 0xff;
PORTB = 0xff;
_delay_ms(200);
/*12个LED全亮*/
PORTD = 0x00;
PORTB = 0xf0;
_delay_ms(200);
/*12个LED全灭*/
PORTD = 0xff;
PORTB = 0xff;
_delay_ms(200);
_delay_ms(500); //延时0.5秒
}
}
* 文件名:闪烁灯2.c
* 描述: 在LED上根据要求,进行不同的显示。
* 杜邦线接法:用8针杜邦线把PD和J38的1--8连接(PD0对应J38的1端)。
用杜邦线把PB0对应J38的9端。
用杜邦线把PB1对应J38的10端。
用杜邦线把PB2对应J38的11端。
用杜邦线把PB3对应J38的12端。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
int main(void)
{
uchar i, temp;
DDRD = 0xff;
DDRB = 0x0f;
PORTB = 0xff;
PORTD = 0xff;
while(1)
{
temp = 0xf7;
for(i=0; i<4; i++)
{
PORTB = temp; //把值赋给P2口
_delay_ms(100); //延时(10毫秒* j)秒
temp = temp >> 1; //值右移一位
temp = temp | 0x08;
}
PORTB = 0xff;
temp = 0x7f;
for(i=0; i<8; i++)
{
PORTD = temp; //把值赋给P1口
_delay_ms(100); //延时(10毫秒* j)秒
temp = temp >> 1; //值右移一位
temp = temp | 0x80;
}
PORTD=0xff;
}
}
* 文件名:闪烁灯2.c
* 杜邦线接法:用8针杜邦线把PD和J38的1--8连接(PD0对应J38的1端)。
用杜邦线把PB0对应J38的9端。
用杜邦线把PB1对应J38的10端。
用杜邦线把PB2对应J38的11端。
用杜邦线把PB3对应J38的12端。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
//定义北面的三个灯的两灭
#define LED1L PORTD&=0XFE //LED1=0 LED1红灯发光
#define LED2L PORTD&=0XFD //LED2=0 LED2黄灯发光
#define LED3L PORTD&=0XFB //LED3=0 LED3绿灯发光
#define LED1M PORTD|=~0XFE //LED1=1 LED红灯不亮
#define LED2M PORTD|=~0XFD //LED2=1 LED黄灯不亮
#define LED3M PORTD|=~0XFB //LED3=1 LED绿灯不亮
//定义东面的三个灯的两灭
#define LED4L PORTD&=0XF7 //LED4=0 LED4红灯发光
#define LED5L PORTD&=0XEF //LED5=0 LED5黄灯发光
#define LED6L PORTD&=0XDF //LED6=0 LED6绿灯发光
#define LED4M PORTD|=~0XF7 //LED4=1 LED红灯不亮
#define LED5M PORTD|=~0XEF //LED5=1 LED黄灯不亮
#define LED6M PORTD|=~0XDF //LED6=1 LED绿灯不亮
//定义南面的三个灯的两灭
#define LED7L PORTD&=0XBF //LED7=0 LED7红灯发光
#define LED8L PORTD&=0X7F //LED8=0 LED8黄灯发光
#define LED9L PORTB&=0XFE //LED9=0 LED9绿灯发光
#define LED7M PORTD|=~0XBF //LED7=1 LED红灯不亮
#define LED8M PORTD|=~0X7F //LED8=1 LED黄灯不亮
#define LED9M PORTB|=~0XFE //LED9=1 LED绿灯不亮
//定义西面的三个灯的两
#define LED10L PORTB&=0XFD //LED10=0 LED10红灯发光
#define LED11L PORTB&=0XFB //LED11=0 LED11黄灯发光
#define LED12L PORTB&=0XF7 //LED12=0 LED12绿灯发光
#define LED10M PORTB|=~0XFD //LED10=1 LED红灯不亮
#define LED11M PORTB|=~0XFB //LED11=1 LED黄灯不亮
#define LED12M PORTB|=~0XF7 //LED12=1 LED绿灯不亮
int main(void)
{ unsigned char i;
DDRD = 0xff; //PD口定义为输出
DDRB = 0x0f; //PB口定义为输出
PORTD = 0xff; //PD口赋值高电平
PORTB = 0x0f; //PB口赋值高电平
while(1)
{ /*南北红灯亮、东西绿灯亮、持续时20秒*/
LED1L; LED2M; LED3M;
LED4M; LED5M; LED6L;
LED7L; LED8M; LED9M;
LED10M; LED11M; LED12L;
/*这里,我们调用_delay_ms()函数的时候,参数不要过大,最好不要超过1000,怕引起溢出*/
for(i=0;i<20;i++)
{
_delay_ms(1000); //延时20个1秒,总共时间20秒
}
/*南北红灯亮、东西黄灯亮、持续时间5秒*/
LED1L; LED2M; LED3M;
LED4M; LED5L; LED6M;
LED7L; LED8M; LED9M;
LED10M; LED11L; LED12M;
for(i=0;i<5;i++)
{
_delay_ms(1000);
}
/*南北绿灯亮、东西红灯亮、持续时间20秒*/
LED1M; LED2M; LED3L;
LED4L; LED5M; LED6M;
LED7M; LED8M; LED9L;
LED10L; LED11M; LED12M;
for(i=0;i<20;i++)
{
_delay_ms(1000);
}
/*南北黄灯亮、东西红灯亮、持续时间5秒*/
LED1M; LED2L; LED3M;
LED4L; LED5M; LED6M;
LED10L; LED11M; LED12M;
for(i=0;i<5;i++)
{
_delay_ms(1000);
}
}
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
//数码管的段码编码
uchar table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//下一行的数组可以显示数值外,还可以显示数码管的点
uchar table_d[16] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
int main(void)
{
uchar i=0;
DDRB = 0xff;
DDRD = 0xff;
PORTB = 0x00; //P2口控制的数码管的位选,当P2口的某一位为低电平时,点亮。
顾客可以修改这里的值。
//比如改为0xfe,就是最后一位数码管亮。
比如改为0x7f,就是最高一位数码管点亮。
while(1)
{
PORTD = table[i % 16]; //在这里取i 的个位数,不带点显示
i++;
_delay_ms(1000); //延时0.5秒后显示下一个数}
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
//数码管的段码编码
uchar table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//下一行的数组可以显示数值外,还可以显示数码管的点
uchar table_d[16] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
int main(void)
{
uchar i,j;
DDRB = 0xff;
DDRD = 0xff;
while(1)
{
for(j=0;j<100;j++)
{
PORTD = table[(i / 10) % 10]; //在这里取i 的个位数,不带点显示
PORTB = 0xfd;
_delay_ms(5); //延时0.5秒后显示下一个数
PORTD = table[i % 10]; //在这里取i 的个位数,不带点显示
PORTB = 0xfe;
_delay_ms(5);
}
i++;
}
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
//数码管的段码编码
uchar table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//下一行的数组可以显示数值外,还可以显示数码管的点
uchar table_d[16] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
int main(void)
{
uchar i=0;
DDRB = 0xff;
DDRD = 0xff;
PORTB = 0xfe;
PORTD = table[6];
while(1);
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
//数码管的段码编码
uchar table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//下一行的数组可以显示数值外,还可以显示数码管的点
uchar table_d[16] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
int main(void)
{
uchar i;
DDRB = 0xff;
DDRD = 0xff;
while(1)
{
PORTB = 0xfe;
for(i=0;i<8;i++)
{
PORTD = table[i]; //在这里取i 的个位数,不带点显示
_delay_ms(3); //延时0.5秒后显示下一个数
PORTB = (PORTB << 1)|0x01;
}
i++;
}
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
//数码管的段码编码
uchar table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//下一行的数组可以显示数值外,还可以显示数码管的点
uchar table_d[16] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
int main(void)
{
uchar i,j,LED_temp;
DDRB = 0xff;
DDRD = 0xff;
while(1)
{
for(j=0;j<40;j++)
{
PORTB = 0xfe;
for(i=0;i<8;i++)
{
PORTD = table[(i + LED_temp) % 8]; //数码管段值//点亮某一位数码管
_delay_ms(2);
PORTB = (PORTB << 1)|0X01;
}
}
LED_temp +=1;
}
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把J11口和J12的1-8连接(J11的1端接J12的8端)。
用8针排线把J13口和J3的1-8连接(PB7接J13的1端)。
//注意这里是P2.7
PD0接J10的1端;PD1接J10的2端;PD2接J10的3端;PD3接J10的4端。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define X164A0 PORTD&=0XFE
#define X164A1 PORTD|=~0XFE
#define X164B0 PORTD&=0XFD
#define X164B1 PORTD|=~0XFD
#define X164CLOCK0 PORTD&=0XFB
#define X164CLOCK1 PORTD|=~0XFB
#define X164CLEAR0 PORTD&=0XF7
#define X164CLEAR1 PORTD|=~0XF7
//数码管的段码编码
uchar table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
//下一行的数组可以显示数值外,还可以显示数码管的点
uchar table_d[16] = {0xbf,0x86,0xdb,0xcf,0xe6,0xed,0xfd,0x87,0xff,0xef,0xf7,0xfc,0xb9,0xde,0xf9,0xf1};
int main(void)
{ uchar i,j,temp; DDRB = 0xff; DDRD = 0xff;
while(1)
{ for(j=0;j<16;j++)
{ X164CLEAR0; X164A1; X164CLEAR1;
temp=table[j];
for(i=0; i<8; i++)
{ if((temp>>i) & 0x01)
{X164B1;}
else
{X164B0;}
X164CLOCK0;
X164CLOCK1;
}
_delay_ms(500);
}
}
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把P0口和J12的1-8连接(P0.0接J12的1端)。
用8针排线把P2口和J13的1-8连接(P2.7接J13的1端)。
//注意这里是P2.7
* 杜邦线接法:用8针排线把J11口和J12的1-8连接(J11的1端接J12的8端)。
用8针排线把J13口和J3的1-8连接(PB7接J13的1端)。
//注意这里是P2.7 PD0接J9的1端;PD1接J9的2端;PD2接J9的3端;PD3接J9的4端;PD4接J9的5端。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define SER0 PORTD&=0XFE
#define SER1 PORTD|=~0XFE
#define SRCLK0 PORTD&=0XFD
#define SRCLK1 PORTD|=~0XFD
#define SRCLR0 PORTD&=0XFB
#define SRCLR1 PORTD|=~0XFB
#define RRCLK0 PORTD&=0XF7
#define RRCLK1 PORTD|=~0XF7
#define E0 PORTD&=0XEF
#define E1 PORTD|=~0XEF
uchar table595[10] = {0x81,0xcf,0x92,0x86,0xcc,0xa4,0xa0,0x8f,0x80,0x84};
int main(void)
{ uchar i,j,temp; DDRD = 0xff; E1;
asm("nop"); E0; SRCLR1;
while(1)
{ for(j=0;j<10;j++)
{ temp=table595[j];
for(i=0;i<8;i++)
{ temp=temp << 1;
if(temp & 0x80)
{SER1;}
else
{SER0;}
SRCLK0; asm("nop"); SRCLK1; asm("nop");
RRCLK0; asm("nop"); RRCLK1;
}
_delay_ms(500);
}
}
}
* 文件名: 数码管显示.c
* 杜邦线接法:用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
PC0--PC4接到J8的1-4端。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define KEY1 (PINC&0X01)
#define KEY2 (PINC&0X02)
#define KEY3 (PINC&0X04)
#define KEY4 (PINC&0X08)
int main(void)
{ DDRB = 0xff; DDRC = 0Xff; DDRD = 0xff;
PORTC = 0xff; PORTB = 0xff; PORTD = 0xff;
while(1)
{ if(PINC != 0xff)
{ delay_ms(20); //20毫秒软件防抖
if(KEY1 == 0)
{ /*西面的三个LED亮*/
PORTD = 0xff; PORTB = 0xf1;
}
else if(KEY2 == 0)
{ /*南面的三个LED亮*/
PORTD = 0x3f; PORTB = 0xfe;
}
else if(KEY3 == 0)
{ /*东面的三个LED亮*/
PORTD = 0xc7;
PORTB = 0xff;
}
else if(KEY4 == 0)
{
/*北面的三个LED亮*/
PORTD = 0xf8;
PORTB = 0xff;
}
_delay_ms(500); //延时0.5秒再进行下次按键的检测}
}
}
/********************************************************************
蜂鸣器发音
* 杜邦线接法:PB0接J19的5端。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define BELL0 PORTB&=0XFE
#define BELL1 PORTB|=~0XFE
int main(void)
{
uint i;
DDRB = 0xff;
while(1)
{
for(i = 0; i < 500; i++)
{
BELL0;
_delay_ms(2); //延时10毫秒
BELL1;
_delay_ms(2); //延时10毫秒
}
}
}
/********************************************************************
蜂鸣器蜂音控制
* 杜邦线接法:PB0接到J19的5端。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define BELL0 PORTB&=0XFE
#define BELL1 PORTB|=~0XFE
int main(void)
{
uint i;
DDRB = 0xff;
while(1)
{
for(i = 0; i < 500; i++)
{
BELL0;
_delay_ms(2); //延时10毫秒
BELL1;
_delay_ms(2); //延时10毫秒
}
for(i = 0; i < 2; i++)
{
_delay_ms(1000);
}
}
}
红外遥控解码
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/wdt.h>
#define Start_T1 TCCR1B|=_BV(CS11);TCNT1=0//复位预计分频器并开启定时器T1
#define Stop_T1 TCCR1B&=~_BV(CS11) //关闭定时器T1
//数码管的段码编码
unsigned char table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
volatile unsigned char i,j,k;
volatile unsigned char IRcode; //定义一个长度为4字节的无符号long类型变量来存储代码
volatile unsigned char IR_OK=0; //IR信号接收有效当程序响应接收以后请马上清零这样才会继续接收下一IR码
volatile unsigned char IR_con=0; //IR信号当前接收位0时表示第0位即同步码(4.5ms高电平) volatile unsigned int Pulse_length=0; //捕获的脉冲宽度
volatile unsigned char ICP_Parity=0; //捕获中断奇偶次计数1时为偶次并在此时判断脉宽
volatile unsigned char address;
volatile unsigned char code_data;
volatile unsigned char code_data1;
unsigned char clrbit;
#define FREQ 8 //定义单片机工作频率为4M
void delay_nms(unsigned int ms) //N ms延时函数
{
for(i=0;i<ms;i++)
_delay_loop_2(FREQ*250);
}
ISR(TIMER1_COMPA_vect)
{
IR_con=0;//重置IR接收位为第0位,为下次接收做准备
TIMSK&=~_BV(OCIE1A); //关闭溢出中断
TCCR1B|=_BV(ICES1); //设置输入捕获上升沿有效
ICP_Parity=0;
Stop_T1;
}
ISR(TIMER1_CAPT_vect)
{
if(!IR_OK)
{
if(ICP_Parity==0)
{
ICP_Parity++;
TIMSK|=_BV(OCIE1A);
TCCR1B&=~_BV(ICES1); //设置输入捕获下降沿有效
Start_T1 ;
}
else
{
Stop_T1;
ICP_Parity=0;
TCCR1B|=_BV(ICES1);//设置输入捕获上升沿有效
Pulse_length=ICR1;
if(IR_con==0)
{
if(Pulse_length>=1750&&Pulse_length<2750)// 如果是引导码(4.5ms) 进入下一个bit的读取
IR_con++;
}
else if(IR_con<33) //接收32位数据
{
code_data>>=1;
if(Pulse_length<950&&Pulse_length>700) //判断是否为1 ( 1.685 ms)
code_data|=0x80;
else
code_data&=0x7f;
IR_con++;
if(IR_con==9)
{
address=code_data;
}
else if(IR_con==17)
{
if(code_data+address!=0xff) IR_con=0;
}
else if(IR_con==25)
{
code_data1=code_data;
}
else if(IR_con==33)
{
IR_con=0; //重置IR接收位为第0位,为下次接收做准备
if(code_data+code_data1==0xff)
{
IR_OK=1; //数据有效
IRcode=code_data1;
}
delay_nms(5); //因为32位数据后面还有一个信号上跳变,所以要适当延时,延时0.65ms以上即可
}
}
}
}
}
int main(void)
{
DDRC = 0xFF;
DDRD = 0xFF;
DDRB = 0x00;
PORTB = 0x01; //设置ICP引脚内部上拉
TCCR1B=_BV(WGM12)|_BV(CS11); //采用8分频这样的话TCNT1的计数时基为2us OCR1A=4000; //TCNT1 计数上限设置IR接收超时这里设置8ms
TIMSK|=_BV(TICIE1); //开启输入捕获中断
TCCR1B|=_BV(ICES1); //输入捕获上升沿有效
while(1)
{
if(IR_OK)
{
IR_OK=0;
}
PORTD = table[IRcode / 10 % 10];
PORTC = 0x01;
_delay_ms(3);
PORTD = table[IRcode % 10];
PORTC = 0x02;
_delay_ms(3);
}
}
/********************************************************************
温度传感器
* 杜邦线接法:PB0接J32的4端。
用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
***********************************************************************/
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/wdt.h>
#define DQ_18B20 (1<<0)
#define DQ_TO_0() (PORTB &= ~DQ_18B20)
#define DQ_TO_1() (PORTB |= DQ_18B20)
#define DQ_status() (PINB & DQ_18B20)
#ifndef CPU_CRYSTAL
#define CPU_CRYSTAL (4)
#endif
#define wait_us(us) _delay_loop_2((unsigned int)((us)*CPU_CRYSTAL/4))
unsigned char temp1;
unsigned char temp2;
unsigned char table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned char ds18b20_reset(void)
{
unsigned char bus_flag;
DQ_TO_0(); // 设置1-wire总线为低电平(占领总线)...
/* 现在延迟480us~960us, 与硬件密切相关,但应尽可能选小值(480us),把抖动留给系统(比如在延迟期间发生中断导致延迟变长)。
*/
wait_us(490); // 490us
DQ_TO_1(); // 设置1-wire总线为高电平(释放总线)
/* 这个浮点数是由编译器计算好的,而不是由你的MCU在运行时临时计算的,所以不会占用用户MCU的时间,不必担心(看看前面的宏你就可以确定了) */
wait_us(67.5); // 最佳时间: 60us+7.5us!(忙延时,只是一种策略)
// 探测总线上是否有器件
if(DQ_status()) bus_flag=0; // 复位单总线但没有发现有器件在线
else bus_flag=1; // 复位单总线并发现有器件在线
/* 保证Master释放总线的时间(不是说总线处于高电平的时间)不小于480us即可,这一时间从读总线状态之前就开始了,所以这里把这个
时间计算在内。
在Master释放总线的前半段,也是被动器件声明它们在线之时。
*/
wait_us(490-67.5); // 490-67.5us
return(bus_flag);
}
void ds18b20_write(unsigned char dat)
{
unsigned char count;
// 每个字节共8位,一次发一位
for(count=0; count<8; count++)
{
DQ_TO_0(); // 设置1-wire总线为低电平
wait_us(2); // about 2us
if(dat&0x01) DQ_TO_1(); // 并串转换,先低位后高位
else DQ_TO_0();
dat >>= 1; // 下一位做好准备
// 60us~120us(实际不能到120us, 因为其它语句也用时间了!)
wait_us(62); // 62us
DQ_TO_1();
wait_us(2); // 2us
}
}
unsigned char ds18b20_read(void)
{
unsigned char count,dat;
dat = 0x00; // 数据接收准备
// 每个字节共8位,一次收一位
for(count=0; count<8; count++)
{
// 从总线拉低到读总线状态,不能大于15us!
DQ_TO_0(); // 设置1-wire总线为低电平(拉低总线以同步)
wait_us(2); // 2us
DQ_TO_1(); // 设置1-wire总线为高电平(释放总线)
wait_us(4); // 4us
dat >>= 1;
if(DQ_status()) dat|=0x80; // 读取总线电平,先收低位再收高位
wait_us(62); // 必须大于60us
}
return(dat);
}
void convert_T(void)
{
if(ds18b20_reset()==1)
{ // 如果复位成功
ds18b20_write(0xcc); // 跳过多器件识别
ds18b20_write(0x44); // 启动温度转换}
}
void read_T(void)
{
unsigned char Lsb,Msb;
if(ds18b20_reset()==1)
{ // 如果复位成功
ds18b20_write(0xcc); // 跳过多器件识别
ds18b20_write(0xbe); // 读暂存器
Lsb=ds18b20_read(); // 低字节
Msb=ds18b20_read(); // 高字节
temp2=Lsb&0x0f;
temp1=(Lsb>>4)|(Msb<<4);
}
}
int main(void)
{ DDRD = 0xff;
DDRC = 0x03;
DDRB = 0x01;
while(1)
{ convert_T();
_delay_ms(5);
read_T();
if(temp1>80) temp1=0;
if(temp2>15) temp2=0;
PORTD = table[temp1/10]; //温度十位
PORTC = 0x01;
_delay_ms(3);
PORTD = table[temp1%10]; //温度十位
PORTC = 0x02;
_delay_ms(3);
}
}
AT24C002读写
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/wdt.h>
#include <avr/eeprom.h>
unsigned char table[16] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f,0x77,0x7c,0x39,0x5e,0x79,0x71};
int main(void)
{
unsigned char buf;
DDRD = 0xff;
DDRB = 0xff;
eeprom_busy_wait(); //等待EEPROM读写就位
buf=eeprom_read_byte(0x00);//将地址0Xff中数据读出装入buf
PORTB = 0xfe;
PORTD = table[buf%10];
buf+=1;
eeprom_busy_wait(); //等待EEPROM读写就位
eeprom_write_byte(0x00,buf); //将开机次数写入地址0X00中去
while(1);
}
/********************************************************************
用K1键控制继电器启停
* 杜邦线接法:PB0接J19的6端。
PC0--PC4接到J8的1-4端。
***********************************************************************/ #include <avr/io.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#define uchar unsigned char
#define uint unsigned int
#define RELAY0 PORTB&=0XFE
#define RELAY1 PORTB|=~0XFE
#define S19 (PINC&0X01)
#define S21 (PINC&0X04)
int main(void)
{
DDRB = 0xff;
DDRC = 0xf0;
PORTC = 0xff;
while(1)
{
if(PINC != 0xff)
{
_delay_ms(20);
if(S19 == 0)
{
RELAY0;
}
if(S21 == 0)
{
RELAY1;
}
}
}
}
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
unsigned char disbuf;
unsigned char adcbuf[8];
//数码管的段码编码
unsigned char table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f}; void AD_init(void)
{ ADMUX=0X60; //参考电压=A VCC 转换结果向左看齐,AD通道0 ADCSRA=0X85; //AD使能,转换时钟选择位=FOSC/32,单次转换
}
unsigned char adc_read(void)
{ unsigned char i;
unsigned int ret;
for(i=0;i<8;i++)
{ ADCSRA|=0X40; //启动转换
while(ADCSRA&0x40);
adcbuf[i]=ADCH;
}
ret=0;
for(i=0;i<8;i++)
{ret+=adcbuf[i];}
ret=ret/8;
return ret;
}
int main(void)
{ DDRC = 0x00; DDRB = 0xff; DDRD = 0xff;
AD_init(); //AD初始化函数
while(1)
{ disbuf=adc_read();
PORTD = table[disbuf/100];
PORTB = 0xfe;
_delay_ms(3);
PORTD = table[(disbuf/10)%10];
PORTB = 0xfd;
_delay_ms(3);
PORTD = table[disbuf%10];
PORTB = 0xfb;
_delay_ms(3);
}
}
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/wdt.h>
//数码管的段码编码
unsigned char table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
unsigned int adbuf;
unsigned char adcbuf[8];
unsigned char adcbufh[8];
unsigned int V olt_mv; //转换后的结果,毫伏
void AD_init(void)
{
ADMUX=0X40; //参考电压=A VCC 转换结果向右看齐,AD通道0
ADCSRA=0X85; //AD使能,转换时钟选择位=FOSC/32,单次转换
}
unsigned int adc_read(void)
{
unsigned char i;
unsigned int ret;
unsigned int reth;
for(i=0;i<8;i++)
{
ADCSRA|=0X40; //启动转换
while(ADCSRA&0x40);
adcbuf[i]=ADCL;
adcbufh[i]=ADCH;
}
ret=0;
for(i=0;i<8;i++)
{
ret+=adcbuf[i];
}
ret=ret/8;
reth=0;
for(i=0;i<8;i++)
{
reth+=adcbufh[i];
}
reth=reth/8;
ret|=(unsigned int)(reth<<8);
return ret;
}
int main(void)
{
long temp32;
DDRC = 0x00;
DDRB = 0xff;
DDRD = 0xff;
AD_init(); //AD初始化函数
while(1)
{
adbuf=adc_read();
temp32=(long)adbuf*5000; //以毫伏为单位要乘以5000,以伏为单位要乘以5
Volt_mv=(unsigned int)(temp32/1023);
PORTD = table[V olt_mv/1000];
PORTB = 0xfe;
_delay_ms(3);
PORTD = table[(V olt_mv/100)%10];
PORTB = 0xfd;
_delay_ms(3);
PORTD = table[(V olt_mv/10)%10];
PORTB = 0xfb;
_delay_ms(3);
PORTD = table[V olt_mv%10];
PORTB = 0xf7;
_delay_ms(3);
}
}
直流电机PWM控制
* 杜邦线接法:PB2接J19的7端。
***********************************************************************/ #include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/wdt.h>
unsigned char pwmbuf;
int main(void)
{
unsigned int i,j;
DDRB = 0x02;
while(1)
{
for(j=0;j<3000;j++)
{
PORTB = 0x00;
_delay_us(i);
PORTB = 0x02;
_delay_us(i00-i);
}
if(i<80) i-=5;
}
}
步进动机控制
* 杜邦线接法:PD2接J19的1端;PD3接J19的2端;PD4接J19的3端;PD5接J19的4端。
***********************************************************************/
#include <avr/io.h>
#define F_CPU 8000000
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
#include <avr/wdt.h>
unsigned char stepcon;
const prog_char step_table[8]=
{
0b00000100,
0b00001100,
0b00001000,
0b00011000,
0b00010000,
0b00110000,
0b00100000,
0b00100100,
};
int main(void)
{
DDRD = 0x3C;
PORTD = 0x00;
while(1)
{
_delay_ms(2);
if(++stepcon>7) stepcon=0;
PORTD=pgm_read_byte(step_table+stepcon);
}
}
串口通信
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#include <util/delay.h>
typedef union
{ unsigned char Byte;
struct
{ unsigned char bit0 :1;
unsigned char bit1 :1;
unsigned char bit2 :1;
unsigned char bit3 :1;
unsigned char bit4 :1;
unsigned char bit5 :1;
unsigned char bit6 :1;
unsigned char bit7 :1;
} Bits;
} BitField;
volatile BitField _FLAG;
#define sendbit _FLAG.Bits.bit0
unsigned char recebuf;
void USARTINT(void)
{ UBRRH=0; UBRRL=25;
UCSRB=(1<<RXEN)|(1<<TXEN);
}
void senddata(unsigned char c)
{ while(!(UCSRA&(1<<UDRE)));
UDR=c;
}
unsigned char loaddata(void)
{ w hile(!(UCSRA&(1<<RXC))) ;
return UDR;
}
int main(void)
{ unsigned char i=48;
DDRC = 0x16; DDRB = 0x3a; DDRD = 0x0;
USARTINT();
while(1)
{ s enddata(i++);
_delay_ms(1000);
}
}
/********************************************************************
时钟芯片DS1302控制
* 杜邦线接法:PC0接J18的1端;PC1接J18的2端;PC2接J18的3端。
用8针排线把PD口和J12的1-8连接(PD.0接J12的1端)。
用8针排线把PB口和J13的1-8连接(PB.7接J13的1端)。
***********************************************************************/ #include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/pgmspace.h>
#define F_CPU 8000000 //这里的值是单片机工作的相关晶振频率
#include <util/delay.h>
#include <avr/wdt.h>
#define T_CLK0 PORTC&=0XFE /*实时时钟时钟线引脚*/
#define T_IO0 PORTC&=0XFD /*实时时钟数据线引脚*/
#define T_RST0 PORTC&=0XFB /*实时时钟复位线引脚*/
#define T_CLK1 PORTC|=~0XFE /*实时时钟时钟线引脚*/
#define T_IO1 PORTC|=~0XFD /*实时时钟数据线引脚*/
#define T_RST1 PORTC|=~0XFB /*实时时钟复位线引脚*/
unsigned char timebuf[7];
//数码管的段码编码
unsigned char table[10] = {0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};
void RTInputByte(unsigned char d)
{
unsigned char i;
for(i=0;i<8;i++)
{
if(d&0x01)
T_IO1;
else
T_IO0;
d=d>>1;
asm("NOP");
T_CLK1;
asm("NOP");
T_CLK0;
asm("NOP");
}
}
unsigned char RTOutputByte(void)
{
unsigned char i,b;
DDRC &= 0xFD;
PORTC |= 0x02;
b=0;
for(i=8; i>0; i--)
{
b= b>>1;
if(PINC&0X02) b|=0x80;
T_CLK1;
asm("NOP");
T_CLK0;
}
DDRC |= 0x02;
return b;
}
void W1302(unsigned char ucAddr, unsigned char ucDa)
{
T_RST0;
T_CLK0;
T_RST1;
RTInputByte(ucAddr); /* 地址,命令*/
RTInputByte(ucDa); /* 写1Byte数据*/
T_CLK1;
T_RST0;
}
unsigned char R1302(unsigned char ucAddr)
{
unsigned char ucData;
T_RST0;
T_CLK0;
T_RST1;
RTInputByte(ucAddr); /* 地址,命令*/
ucData = RTOutputByte(); /* 读1Byte数据*/ T_CLK1;
T_RST0;
return(ucData);
}
void BurstW1302T(unsigned char *pWClock)
{
unsigned char i;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作?*/
T_RST0;
T_CLK0;
T_RST1;
RTInputByte(0xbe); /* 0xbe:时钟多字节写命令*/
for (i = 8; i>0; i--) /*8Byte = 7Byte 时钟数据+ 1Byte 控制*/ {
RTInputByte(*pWClock); /* 写1Byte数据*/
pWClock++;
}
T_CLK1;
T_RST0;
}
void BurstR1302T(unsigned char *pRClock)
{
unsigned char i;
T_RST0;
T_CLK0;
T_RST1;
RTInputByte(0xbf); /* 0xbf:时钟多字节读命令*/ for (i=8; i>0; i--)
{
*pRClock = RTOutputByte(); /* 读1Byte数据*/
pRClock++;
}
T_CLK1;
T_RST0;
}
void BurstW1302R(unsigned char *pWReg)
{
unsigned char i;
W1302(0x8e,0x00); /* 控制命令,WP=0,写操作*/
T_RST0;
T_CLK0;
T_RST1;
RTInputByte(0xfe); /* 0xbe:时钟多字节写命令*/
for (i=31; i>0; i--) /* 31Byte 寄存器数据*/
{
RTInputByte(*pWReg); /* 写1Byte数据*/
pWReg++;
}。