您好,欢迎来到吉趣旅游网。
搜索
您的当前位置:首页ATmega128几个常用程序例子

ATmega128几个常用程序例子

来源:吉趣旅游网
ATMEGA128相关例程

自己学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<ADCSRA = (1</**************************************************************************** 函数功能:ADC中断函数 入口参数: 出口参数:

****************************************************************************/ #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<if(adc_rel>0x1ff) {

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 led0_en() {DDRB|=1<<4;PORTB|=(1<<4);} #define led0_dis() {DDRB|=1<<4;PORTB&=~(1<<4);} #define led1_en() {DDRB|=1<<5;PORTB|=(1<<5);} #define led1_dis() {DDRB|=1<<5;PORTB&=~(1<<5);} #define led2_en() {DDRB|=1<<6;PORTB|=(1<<6);} #define led2_dis() {DDRB|=1<<6;PORTB&=~(1<<6);} #define led3_en() {DDRB|=1<<7;PORTB|=(1<<7);} #define led3_dis() {DDRB|=1<<7;PORTB&=~(1<<7);}

开第一个数码管的位选 关第一个数码管的位选 // //#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;ivoid delay_1ms(void) //1ms延时函数 {

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/*完成spi的初始化*/ void spi_init(void) {

DDRB |= (1<SPCR = (1</*spi主机传送数据*/

void SPI_MasterTransmit(char Data) {

/* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */ while(!(SPSR & (1</*完成对HC595的初始化*/ void HC_595_init(void) {

DDRC |= (1<PORTC &= (1<PORTB = 0x0F; //同时打开四个数码管的位选 spi_init();

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<HC_595_OUT(table[led_buffer[3]]); led0_en(); delay_nus(60); led0_dis();

if(point==1)

HC_595_OUT(table[led_buffer[2]]|(1<HC_595_OUT(table[led_buffer[2]]); led1_en(); delay_nus(60); led1_dis();

if(point==2)

HC_595_OUT(table[led_buffer[1]]|(1<HC_595_OUT(table[led_buffer[1]]); led2_en(); delay_nus(60); led2_dis();

/*最高位数码管,第一个数码管*/ if(point==3)

HC_595_OUT(table[led_buffer[0]]|(1<HC_595_OUT(table[led_buffer[0]]); led3_en(); delay_nus(60); led3_dis(); }

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<EECR |=(1</*从EEPROM指定的地址里面读出相应的数据*/ unsigned char EEPROM_read(unsigned int uiAddress) {

while(EECR&(1<return EEDR; //返回读入EEDR里面的数据 }

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<UBRR0L=(fosc/16/(baud+1))%256; //异步正常情况下的计算公式 UBRR0H=(fosc/16/(baud+1))/256;

UCSR0B =(1</**************************************************************************** 函数功能:uart0发送单字节数据 入口参数:c 出口参数:

****************************************************************************/ void putchar0(unsigned char c) {

while (!(UCSR0A&(1</**************************************************************************** 函数功能:uart0接收单字节数据 入口参数: 出口参数:

****************************************************************************/ unsigned char getchar0(void) {

while(!(UCSR0A& (1</**************************************************************************** 函数功能:uart0发送字符串数据 入口参数:*s 出口参数:

****************************************************************************/ 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<UBRR1L=(fosc/16/(baud+1))%256;//异步正常模式下,UBRR的计算公式 UBRR1H=(fosc/16/(baud+1))/256;

UCSR1B =(1</**************************************************************************** 函数功能:uart1发送单字节数据

入口参数:c 出口参数:

****************************************************************************/ void putchar1(unsigned char c)//串口1发送字符 {

while (!(UCSR1A&(1</**************************************************************************** 函数功能:uart1接收单字节数据 入口参数: 出口参数:

****************************************************************************/ unsigned char getchar1(void) //串口1接回收数据 {

while(!(UCSR1A& (1<return UDR1; //将接收到的字符返回 }

/**************************************************************************** 函数功能: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<SPCR = (1</************************************************************************* ** 函数名称: SPI_MasterTransmit(char Data) ** 功能描述: SPI主机发送数据

** 输 入: Data 需要通过SPI传输的数据 ** 输出 : ** 全局变量: 无 ** 调用模块: ** 说明: ** 注意:

**************************************************************************/ void SPI_MasterTransmit(char Data) {

/* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */

while(!(SPSR & (1<11、PWM波形输出 #include <> #include<>

#define uint unsigned int #define uchar unsigned char void delay_ms(uint n) {uint i=0,j; while(i{for(j=0;j<1000;j++); 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<#define led0_en() {DDRB|=1<<4;PORTB|=(1<<4);} //开第一个数码管的位选 #define led0_dis() {DDRB|=1<<4;PORTB&=~(1<<4);} //关第一个数码管的位选 #define led1_en() {DDRB|=1<<5;PORTB|=(1<<5);} #define led1_dis() {DDRB|=1<<5;PORTB&=~(1<<5);} #define led2_en() {DDRB|=1<<6;PORTB|=(1<<6);} #define led2_dis() {DDRB|=1<<6;PORTB&=~(1<<6);} #define led3_en() {DDRB|=1<<7;PORTB|=(1<<7);} #define led3_dis() {DDRB|=1<<7;PORTB&=~(1<<7);} #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) {

unsigned int i=0; for (i=0;ivoid delay_1ms(void) {

unsigned int i; for (i=0;i<1140;i++); }

void delay_nms(unsigned int n) {

unsigned int i=0; for (i=0;i//N us延时函数 //1ms延时函数 //N ms延时函数 /*完成spi的初始化*/ void spi_init(void) {

DDRB |= (1<SPCR = (1</*spi主机传送数据*/

void SPI_MasterTransmit(char Data) {

/* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */ while(!(SPSR & (1</*完成对HC595的初始化*/ void HC_595_init(void) {

DDRC |= (1<PORTB = 0x0F; //同时打开四个数码管的位选 spi_init();

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<HC_595_OUT(table[led_buffer[3]]); led0_en(); delay_nus(60); led0_dis();

if(point==1)

HC_595_OUT(table[led_buffer[2]]|(1<HC_595_OUT(table[led_buffer[2]]); led1_en(); delay_nus(60); led1_dis();

if(point==2)

HC_595_OUT(table[led_buffer[1]]|(1<HC_595_OUT(table[led_buffer[1]]); led2_en(); delay_nus(60); led2_dis();

/*最高位数码管,第一个数码管*/ if(point==3)

HC_595_OUT(table[led_buffer[0]]|(1<HC_595_OUT(table[led_buffer[0]]); led3_en(); delay_nus(60); led3_dis(); }

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</*********************************包含头文件********************************/ #include <> #include <> #include \"\"

/**********************************全局变量*********************************/ 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 led0_en() {DDRB|=1<<4;PORTB|=(1<<4);} #define led0_dis() {DDRB|=1<<4;PORTB&=~(1<<4);} #define led1_en() {DDRB|=1<<5;PORTB|=(1<<5);} #define led1_dis() {DDRB|=1<<5;PORTB&=~(1<<5);} #define led2_en() {DDRB|=1<<6;PORTB|=(1<<6);} #define led2_dis() {DDRB|=1<<6;PORTB&=~(1<<6);} #define led3_en() {DDRB|=1<<7;PORTB|=(1<<7);} #define led3_dis() {DDRB|=1<<7;PORTB&=~(1<<7);}

//开第一个数码管的位选 //关第一个数码管的位选 #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;ivoid delay_1ms(void) //1ms延时函数 {

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/*完成spi的初始化*/ void spi_init(void) {

DDRB |= (1<SPCR = (1</*spi主机传送数据*/

void SPI_MasterTransmit(char Data) {

/* 启动数据传输 */ SPDR = Data; /* 等待传输结束 */ while(!(SPSR & (1</*完成对HC595的初始化*/ void HC_595_init(void) {

DDRC |= (1<PORTB = 0x0F; //同时打开四个数码管的位选 spi_init();

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<HC_595_OUT(table[led_buffer[3]]); led0_en();

delay_nus(60); led0_dis();

if(point==1)

HC_595_OUT(table[led_buffer[2]]|(1<HC_595_OUT(table[led_buffer[2]]); led1_en(); delay_nus(60); led1_dis();

if(point==2)

HC_595_OUT(table[led_buffer[1]]|(1<HC_595_OUT(table[led_buffer[1]]); led2_en(); delay_nus(60); led2_dis();

/*最高位数码管,第一个数码管*/ if(point==3)

HC_595_OUT(table[led_buffer[0]]|(1<HC_595_OUT(table[led_buffer[0]]); led3_en(); delay_nus(60); led3_dis();

}

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

本站由北京市万商天勤律师事务所王兴未律师提供法律服务