ATmega128实例程序要点
- 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
- 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
- 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。
1、流水灯 (1)
2、AD转换+数码管显示 (2)
3、对EEPROM进行读写操作 (8)
4、定时器0(轮循方式) (9)
5、定时器0中中断 (10)
6、定时器1测试程序 (12)
7、定时器1测试程序之二 (14)
8、串口通信(USART0) (15)
9、串口通信(USART1) (17)
10、ATMEGA128 SPI驱动 (20)
11、PWM波形输出 (21)
12、定时器1数码管显示(1s) (22)
13、定时器1:定时计数(1s) (27)
14、外部中断0-3 (32)
15、定时器3 pwm输出 (34)
16、定时器0,快速PWM模式 (35)
17、定时器0,相位修正(调整)模式 (36)
18、定时器1pwm波形输出 (38)
19、定时器3,OCRB3输出PWM波形,占空比可调 (39)
1、流水灯
/*
硬件环境:atmega128开发板
软件环境:CodeVisionAVR-C
*/
#include <mega128.h>
#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 7.13A */
/*E-Mail:number007cool@ */
/*时间:2010年11月13日*/
//Aref接AVCC(+5V),采用Aref作参考电压
/*用数码管显示AD转换的结果*/
/***************************************************************************/ /*********************************包含头文件********************************/ #include <iom128v.h>
#include <macros.h>
/********************************数码管段码表*******************************/ 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<<ACD);
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
//ADEN,启动ADC;ADSC,ADC开始转换;ADIE,ADC中断使能;ADPSx,设置分频因子64 }
/****************************************************************************
函数功能: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<<ADEN)|(1<<ADSC)|(1<<ADIE);
adc_rel=ADC;
/*
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<<SS)
#define SS_L() PORTB&=~(1<<SS)
#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 <iom128v.h>
#include <macros.h>
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<n;i++)
delay_1us();
}
void 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<n;i++)
delay_1ms();
}
/*完成spi的初始化*/
void spi_init(void)
{
DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS);//设置MOSI,SCK输出
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI,主机模式}
/*spi主机传送数据*/
void SPI_MasterTransmit(char Data)
{
/* 启动数据传输*/
SPDR = Data;
/* 等待传输结束*/
while(!(SPSR & (1<<SPIF)))
;
}
/*完成对HC595的初始化*/
void HC_595_init(void)
{
DDRC |= (1<<OE); //设置PORTC7为输出
PORTC &= (1<<OE); //输出高电平,使能595
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<<dp));
else
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<<dp));
else
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<<dp));
else
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<<dp));
else
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/1024.0*5*1000);
}
}
3、对EEPROM进行读写操作
/************************************************
文件:main.c
用途:
注意:内部8M晶振
************************************************/
#include "config.h"
/*向EEPROM里面写入数据
输入量:地址,数据*/
void EEPROM_write(unsigned int uiAddress,unsigned char ucData)
{
while(EECR&(1<<EEWE)); //等待上一次写操作结束
EEAR = uiAddress; //地址
EEDR = ucData; //数据
EECR |=(1<<EEMWE); //置位EEMWE,主机写使能
EECR |=(1<<EEWE); //置位EEWE,写使能,启动写操作
}
/*从EEPROM指定的地址里面读出相应的数据*/
unsigned char EEPROM_read(unsigned int uiAddress)
{
while(EECR&(1<<EEWE)); //等待上一次写操作结束
EEAR = uiAddress; //设置地址寄存器
EECR |=(1<<EERE); //读使能
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); //调用显示函数将写入的数据又读出来
}
}
4、定时器0(轮循方式)
/*定时器0和2(均为八位的定时计数器)有四种工作模式,此例是工作在普通模式。
在此模式下,计数器不断的累加,当计数到最大值0xff后返回到0x00重新开始,在TCNT0 为0 的同时,T/C溢出标志TOV0置位*/
//使用轮循方式,当TIFR溢出时,uc_led加1,输出到led时期发光
//TIFR中断标志寄存器
#include <iom128v.h>
#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 7.13 */
/*E-Mail:number007cool@ */
/*时间:2010年3月14日*/
/*TCCRn定时计数器控制寄存器
TCNTn计数器,不断的计数
TIMSK定时计数器中断屏蔽寄存器
TIFR中断标志寄存器
*/
/***************************************************************************/
#include <iom128v.h>
#include <macros.h>
/**********************************全局变量*********************************/ 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 <iom128v.h>
#include <macros.h>
/**********************************全局变量*********************************/ 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 0.2s设置高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 <iom128v.h>
#include <macros.h>
/**********************************全局变量*********************************/ int countnum;
/**************************************************************************** 函数功能:端口初始化程序
入口参数:
出口参数:
****************************************************************************/ void port_init (void)
{
DDRE|=1<<2;
PORTE|=1<<2;
DDRA=0XFF;
PORTA=0X00;
}
/**************************************************************************** 函数功能:定时器初始化程序
入口参数:
出口参数:
****************************************************************************/ 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 7.13A */
/*时间:2010年3月14日*/
/*E-Mail:number007cool@ */
/***************************************************************************/
#include<iom128v.h>
#include<macros.h>
/***********************************宏定义**********************************/ #define fosc 8000000 //晶振8MHZ
#define baud 2400 //波特率
/**************************************************************************** 函数功能:uart0初始化程序
入口参数:
出口参数:
****************************************************************************/ void uart0_init(void)
{
UCSR0B = 0x00; //关闭UART00
UCSR0A = 0x00; //不使用倍速发送(异步)
UCSR0C =(1<<UCSZ01)|(1<<UCSZ00); //数据位为8位
UBRR0L=(fosc/16/(baud+1))%256; //异步正常情况下的计算公式
UBRR0H=(fosc/16/(baud+1))/256;
UCSR0B =(1<<RXEN0)|(1<<TXEN0); //接收使能和发送使能
}
/**************************************************************************** 函数功能:uart0发送单字节数据
入口参数:c
出口参数:
****************************************************************************/ void putchar0(unsigned char c)
{
while (!(UCSR0A&(1<<UDRE0)));//表明发送器已经准备就绪
UDR0=c; //将要发送的数据装入UDR0寄存器
}
/**************************************************************************** 函数功能:uart0接收单字节数据
入口参数:
出口参数:
****************************************************************************/ unsigned char getchar0(void)
{
while(!(UCSR0A& (1<<RXC0)));//表明已经接收完毕
return UDR0;
}
/**************************************************************************** 函数功能: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 7.13 */
/*E-Mail:number007cool@ */
/*时间:2010年1月14日*/
/***************************************************************************/ /*********************************包含头文件********************************/ #include<iom128v.h>
#include<macros.h>
#define fosc 8000000 //晶振8MHZ
#define baud 9600 //波特率
/**************************************************************************** 函数功能:uart1初始化程序
入口参数:
出口参数:
****************************************************************************/ void uart1_init(void) //USART1初始化
{
UCSR1B = 0x00; //关闭USART1
UCSR1A = 0x00; //不适使用倍速发送
UCSR1C = (1<<UCSZ11)|(1<<UCSZ10);//数据位为八位
UBRR1L=(fosc/16/(baud+1))%256;//异步正常模式下,UBRR的计算公式
UBRR1H=(fosc/16/(baud+1))/256;
UCSR1B =(1<<RXEN1)|(1<<TXEN1); //接收使能,传送使能
}
/**************************************************************************** 函数功能:uart1发送单字节数据
入口参数:c
出口参数:
****************************************************************************/ void putchar1(unsigned char c)//串口1发送字符
{
while (!(UCSR1A&(1<<UDRE1)));//表明发送器一准备就绪
UDR1=c;
}
/**************************************************************************** 函数功能:uart1接收单字节数据
入口参数:
出口参数:
****************************************************************************/ unsigned char getchar1(void) //串口1接回收数据
{
while(!(UCSR1A& (1<<RXC1)));
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.c
用途:SPI驱动
/*************************************************************************
** 函数名称: spi_init(void)
** 功能描述: SPI初始化
** 输入:
** 输出:
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void spi_init(void)
{
DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS); //设置MOSI和SCK输出
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1); //使能SPI,主机模式
//SPE,使能SPI;MSTR,主机模式;SPR0和SPR1设置时钟频率
}
/*************************************************************************
** 函数名称: SPI_MasterTransmit(char Data)
** 功能描述: SPI主机发送数据
** 输入: Data 需要通过SPI传输的数据
** 输出:
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/ void SPI_MasterTransmit(char Data)
{
/* 启动数据传输*/
SPDR = Data;
/* 等待传输结束*/
while(!(SPSR & (1<<SPIF))) //串行发送结束以后SPIF置位(即为1)
;
}
11、PWM波形输出
#include <iom128v.h>
#include<macros.h>
#define uint unsigned int
#define uchar unsigned char
void delay_ms(uint n)
{uint i=0,j;
while(i<n)
{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;
}
}
12、定时器1数码管显示(1s)
config.h文件
/*时间误差:0.00672秒每秒*/
#define SS 0
#define SCK 1
#define MOSI 2
#define MISO 3
#define SS_H() PORTB|=(1<<SS)
#define SS_L() PORTB&=~(1<<SS)
//注意,不要漏掉了()
#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 <iom128v.h>
#include <macros.h>
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<n;i++)
delay_1us();
}
void 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<n;i++)
delay_1ms();
}
/*完成spi的初始化*/
void spi_init(void)
{
DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS);//设置MOSI,SCK输出
SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI,主机模式}
/*spi主机传送数据*/
void SPI_MasterTransmit(char Data)
{
/* 启动数据传输*/
SPDR = Data;
/* 等待传输结束*/
while(!(SPSR & (1<<SPIF)))
;
}
/*完成对HC595的初始化*/
void HC_595_init(void)
{
DDRC |= (1<<OE); //设置PORTC7为输出
PORTC &= (1<<OE); //输出高电平,使能595
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<<dp));
else
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<<dp));
else
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<<dp));
else
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<<dp));
else
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[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<<TOIE1);
}
main.c文件
/*********************************包含头文件********************************/
#include <macros.h>
#include "config.h"
/**********************************全局变量*********************************/ 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=0.99328s
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)
}
}
/**************************************************************************** 函数功能:主程序
入口参数:
出口参数:
****************************************************************************/ void main (void)
{
CLI(); //disable all interrupts
init_devices();
MCUCR = 0x00;
TIMSK = 0x04; //T0溢出使能
SEI(); //enable interrupts
while(1)
{
display_led(cnt);
}
}
13、定时器1:定时计数(1s)
main.c文件:
/*********************************包含头文件********************************/ #include <iom128v.h>
#include <macros.h>
#include "config.h"
/**********************************全局变量*********************************/ int k;
volatile unsigned int cnt;
unsigned char fenpin[]={0x01,0x02,0x03,0x04,0x05};
//分频系数分别为:1,8,64,256,1024;
/**************************************************************************** 函数功能:定时器初始化程序
入口参数:
出口参数:
****************************************************************************/ void timer1_init(void)
{
TCCR1B = 0x00; //stop
TCNT1H = 0xF0; //setup 1s
TCNT1L = 0xBE; //(16*16*15+4*16)*1024/8000000*2=0.999424S
TCCR1A = 0x00;
TCCR1B = fenpin[4]; //start Timer 1024。