Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1955618
  • 博文数量: 356
  • 博客积分: 8284
  • 博客等级: 中将
  • 技术积分: 4580
  • 用 户 组: 普通用户
  • 注册时间: 2009-05-15 20:25
个人简介

天行健,君子以自强不息

文章分类

全部博文(356)

文章存档

2018年(1)

2016年(4)

2015年(13)

2014年(14)

2013年(2)

2012年(25)

2011年(43)

2010年(65)

2009年(189)

分类: C/C++

2010-03-10 21:08:31

自己学avr单片机已经有相当一段时间了,一开始用的是atmega128,觉得不是很好用。于是自己去买了一块16L的芯片,觉得还行。一开始用的是ICC AVR,应为它用起来比较简单,不像winavr那样,要写个Makefie
,比较的麻烦,但icc avr的缺点是太过于简陋,调试程序时,感觉不是很好。后来经同学介绍,用起了winavr,其实也是比较的简单,只不过要加一个makefile而已,其实makefile可以用软件自带的组建自动生成,只需修改几个参数就可以用。后来又用起了code vision avr,虽然不太习惯,也谈不上不好用.
需要注意的是,三个不同的软件所带的同文件不一样。icc avr 是iom128v.h(姑且以128为例),winavr是avr/io.h,不过makefile中要设置芯片为atmega128.而cvavr则是mega128.h。
记得一开始的时候,我对这些不同的同文件不是很理解,是从一个学长那里了解到,才弄明白的。其实前两个软件只需把头文件稍微改一下基本上可以通用。而最后一个软件的中断的写法似乎不太一样,因而和钱两个软件的兼容性是最差的。
总体说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 7.13A                                 */
/*E-Mail:number007cool@163.com                                             */
/*时间: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<//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<  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<#define SS_L() 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;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   delay_1ms();
  }

/*完成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<  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<  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<  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<  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< EEAR = uiAddress;     //地址
 EEDR = ucData;      //数据
 EECR |=(1< EECR |=(1<}
/*从EEPROM指定的地址里面读出相应的数据*/
unsigned char EEPROM_read(unsigned int uiAddress)
{
 while(EECR&(1< EEAR = uiAddress;       //设置地址寄存器
 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);  //调用显示函数将写入的数据又读出来
 }
}
文件: eeprom12.rar
大小: 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 7.13                                        */
/*E-Mail:number007cool@163.com                                             */
/*时间: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  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
#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 7.13A                                 */
/*时间:2010年3月14日*/
/*E-Mail:number007cool@163.com                                             */
/***************************************************************************/
/*********************************包含头文件********************************/
#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<    UDR0=c;    //将要发送的数据装入UDR0寄存器
 } 
 
/****************************************************************************
函数功能:uart0接收单字节数据
入口参数:
出口参数:
****************************************************************************/
unsigned char getchar0(void)
   {
    while(!(UCSR0A& (1<       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@163.com                                             */
/*时间: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<  UDR1=c;   
 } 
 
/****************************************************************************
函数功能: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.c
用途:SPI驱动
/*************************************************************************
** 函数名称: spi_init(void)
** 功能描述: SPI初始化
** 输 入:
** 输出  :
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void spi_init(void)
{
   DDRB |= (1<//设置MOSI和SCK输出
   SPCR = (1<   
//SPE,使能SPI;MSTR,主机模式;SPR0和SPR1设置时钟频率
}
/*************************************************************************
** 函数名称: SPI_MasterTransmit(char Data)
** 功能描述: SPI主机发送数据
** 输 入: Data 需要通过SPI传输的数据
** 输出  :
** 全局变量: 无
** 调用模块:
** 说明:
** 注意:
**************************************************************************/
void SPI_MasterTransmit(char Data)
{
   /* 启动数据传输 */
   SPDR = Data;
   /* 等待传输结束 */
   while(!(SPSR & (1<)))   //串行发送结束以后SPIF置位(即为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)
config.h文件
/*时间误差:0.00672秒每秒*/
#define SS 0
#define SCK 1
#define MOSI 2
#define MISO 3
#define SS_H() PORTB|=(1<#define SS_L() 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;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   delay_1ms();
  }
/*完成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<  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<  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<  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<  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]=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<}
main.c文件
 
/*********************************包含头文件********************************/
#include
#include
#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)
    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)
main.c文件:

/*********************************包含头文件********************************/
#include
#include
#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
 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);
  } 
}
config.h文件:

/*时间误差:0.00672秒每秒*/
#define SS 0
#define SCK 1
#define MOSI 2
#define MISO 3
#define SS_H() PORTB|=(1<#define SS_L() 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;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   delay_1ms();
  }
/*完成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<  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<  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<  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<  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]=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=977.5HZ
=======================================================*/
#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--);
 }
}


转载请注明出处:
阅读(14656) | 评论(1) | 转发(3) |
给主人留下些什么吧!~~

peng199912202014-02-18 10:16:00

向版主学习,谢谢分享