找回密碼
 立即注冊

QQ登錄

只需一步,快速開始

搜索
查看: 3343|回復(fù): 0
收起左側(cè)

AVR128單片機(jī)基礎(chǔ)例程分享

[復(fù)制鏈接]
ID:869129 發(fā)表于 2020-12-28 08:05 | 顯示全部樓層 |閱讀模式
1、流水燈
/*
硬件環(huán)境:atmega128開發(fā)板
軟件環(huán)境:CodeVisionAVR-C
*/
#include <mega128.h>
#define  uchar unsigned char
#define  uint  unsigned int
uchar cnt;
void timer1_init()
{
    TCCR1B=0X00;   //先停止定時(shí)器1
    TCNT1H=0XF0;   //設(shè)定定時(shí)器初值
    TCNT1L=0XBE;   
    TCCR1A=0X00;   //啟動(dòng)定時(shí)器1
    TCCR1B=0X05;   //使用1024分頻
}
interrupt [TIM1_OVF] void timer1_ovf_isr(void)
{
      TCNT1H=0XF0;      //重載定時(shí)器初值
      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轉(zhuǎn)換+數(shù)碼管顯示
/***************************************************************************/
/*ADC測試程序                                          */
/*目標(biāo)器件:ATmega128                                  */
/*晶振:RC 8MHZ                                       */
/*編譯環(huán)境:ICCAVR 7.13A                                 */
//Aref接AVCC(+5V),采用Aref作參考電壓
/*用數(shù)碼管顯示AD轉(zhuǎn)換的結(jié)果*/
/***************************************************************************/
/*********************************包含頭文件********************************/
#include <iom128v.h>
#include <macros.h>
/********************************數(shù)碼管段碼表*******************************/
extern const unsigned char tab[]={0x3f,0x06,0x5B,0x4F,0x66,0x6D,0x7D,0x07,
                                  0x7F,0x6F};
/*********************************全局變量**********************************/
unsigned int adc_rel=0;
/****************************************************************************
函數(shù)功能:ADC初始化函數(shù)
入口參數(shù):
出口參數(shù):
****************************************************************************/
void adc_init(void)
{
DDRF&=0XFE;      //PORTF0設(shè)置為輸入,即作為ADC0口輸入模擬電壓
PORTF&=0XFE;  //PORTF0設(shè)置為輸入低電平
ADCSRA=0x00;  //關(guān)ADC
ADMUX = 0X00;       //采用Aref作為參考電壓,ADC0單端輸入,右對齊
ACSR=(1<<ACD);
ADCSRA = (1<<ADEN)|(1<<ADSC)|(1<<ADATE)|(1<<ADIE)|(1<<ADPS2)|(1<<ADPS1);
//ADEN,啟動(dòng)ADC;ADSC,ADC開始轉(zhuǎn)換;ADIE,ADC中斷使能;ADPSx,設(shè)置分頻因子64
}
/****************************************************************************
函數(shù)功能:ADC中斷函數(shù)
入口參數(shù):
出口參數(shù):
****************************************************************************/
#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);
   */
}

/****************************************************************************
函數(shù)功能:延時(shí)子程序
入口參數(shù):
出口參數(shù):
****************************************************************************/
void delay(void)
{
   int i;
    for(i=0;i<1800;i++);
}
/****************************************************************************
函數(shù)功能:顯示子程序
入口參數(shù):k
出口參數(shù):
****************************************************************************/
void display(unsigned int k)//發(fā)光二極管顯示初始化
{
  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);}     //開第一個(gè)數(shù)碼管的位選
#define led0_dis() {DDRB|=1<<4;PORTB&=~(1<<4);}    //關(guān)第一個(gè)數(shù)碼管的位選
#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延時(shí)函數(shù)
  {
   asm("nop");
  }
void delay_nus(unsigned int n)       //N us延時(shí)函數(shù)
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1us();
  }
  
void delay_1ms(void)                 //1ms延時(shí)函數(shù)
  {
   unsigned int i;
   for (i=0;i<1140;i++);
  }
  
void delay_nms(unsigned int n)       //N ms延時(shí)函數(shù)
  {
   unsigned int i=0;
   for (i=0;i<n;i++)
   delay_1ms();
  }

/*完成spi的初始化*/
void spi_init(void)
{
   DDRB |= (1<<MOSI)|(1<<SCK)|(1<<SS);//設(shè)置MOSI,SCK輸出
   SPCR = (1<<SPE)|(1<<MSTR)|(1<<SPR0)|(1<<SPR1);//使能SPI,主機(jī)模式
}
/*spi主機(jī)傳送數(shù)據(jù)*/
void SPI_MasterTransmit(char Data)
{
   /* 啟動(dòng)數(shù)據(jù)傳輸 */
   SPDR = Data;
   /* 等待傳輸結(jié)束 */
   while(!(SPSR & (1<<SPIF)))
   ;
}
/*完成對HC595的初始化*/
void HC_595_init(void)
{
DDRC |= (1<<OE);   //設(shè)置PORTC7為輸出
PORTC &= (1<<OE);  //輸出高電平,使能595
PORTB = 0x0F;      //同時(shí)打開四個(gè)數(shù)碼管的位選
spi_init();
led_buffer[0]=16;  //初始化數(shù)碼管段碼
led_buffer[1]=16;
led_buffer[2]=16;
led_buffer[3]=16;
}
/*HC595完成傳送數(shù)據(jù)*/
void HC_595_OUT(unsigned char data)
{
   SS_L();
  SPI_MasterTransmit(data);
   SS_H();
}
void leddis_update(void)
{
  /*最低位數(shù)碼管,第四個(gè)數(shù)碼管*/
  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();

  /*最高位數(shù)碼管,第一個(gè)數(shù)碼管*/
  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);//當(dāng)計(jì)數(shù)大于9999時(shí),四個(gè)數(shù)碼管同時(shí)輸出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;         //關(guān)閉最高位的那個(gè)數(shù)碼管
  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
}
/****************************************************************************
函數(shù)功能:主程序
入口參數(shù):
出口參數(shù):
****************************************************************************/
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進(jìn)行讀寫操作
/************************************************
文件:main.c
用途:
注意:內(nèi)部8M晶振
************************************************/
#include "config.h"
/*向EEPROM里面寫入數(shù)據(jù)
輸入量:地址,數(shù)據(jù)*/
void EEPROM_write(unsigned int uiAddress,unsigned char ucData)
{
while(EECR&(1<<EEWE));    //等待上一次寫操作結(jié)束
EEAR = uiAddress;     //地址
EEDR = ucData;      //數(shù)據(jù)
EECR |=(1<<EEMWE);     //置位EEMWE,主機(jī)寫使能
EECR |=(1<<EEWE);     //置位EEWE,寫使能,啟動(dòng)寫操作
}
/*從EEPROM指定的地址里面讀出相應(yīng)的數(shù)據(jù)*/
unsigned char EEPROM_read(unsigned int uiAddress)
{
while(EECR&(1<<EEWE));  //等待上一次寫操作結(jié)束
EEAR = uiAddress;       //設(shè)置地址寄存器
EECR |=(1<<EERE);       //讀使能
return EEDR;            //返回讀入EEDR里面的數(shù)據(jù)
}
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);  //調(diào)用顯示函數(shù)將寫入的數(shù)據(jù)又讀出來
}
}


4、定時(shí)器0(輪循方式)
/*定時(shí)器0和2(均為八位的定時(shí)計(jì)數(shù)器)有四種工作模式,此例是工作在普通模式。
在此模式下,計(jì)數(shù)器不斷的累加,當(dāng)計(jì)數(shù)到最大值0xff后返回到0x00重新開始,在TCNT0
為0 的同時(shí),T/C溢出標(biāo)志TOV0置位*/
//使用輪循方式,當(dāng)TIFR溢出時(shí),uc_led加1,輸出到led時(shí)期發(fā)光
//TIFR中斷標(biāo)志寄存器
#include <iom128v.h>
#define uchar unsigned char
uchar uc_led,k;
void main()
{
//設(shè)置數(shù)碼管輸出高電平
DDRE|=1<<2;     
PORTE|=1<<2;
DDRA=0XFF;
PORTF=0XFF;

TCNT0=0X00;//設(shè)定定時(shí)計(jì)數(shù)器的初值為0
TCCR0=0X05;//使用1024分頻(共有7種時(shí)鐘)
uc_led=0;
k=0;

while(1)
{
  while(!(TIFR&0X01));//循環(huán)檢測TIFR中的溢出標(biāo)志是否有效
  //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位清除溢出標(biāo)志為TOV0
}
}
5、定時(shí)器0中中斷
/***************************************************************************/
/*定時(shí)器T0測試程序                                      */
/*目標(biāo)器件:ATmega128                                  */
/*晶振:RC 8MHZ                                       */
/*TCCRn定時(shí)計(jì)數(shù)器控制寄存器
  TCNTn計(jì)數(shù)器,不斷的計(jì)數(shù)
  TIMSK定時(shí)計(jì)數(shù)器中斷屏蔽寄存器
  TIFR中斷標(biāo)志寄存器
*/
/***************************************************************************/
/*********************************包含頭文件********************************/
#include <iom128v.h>
#include <macros.h>
/**********************************全局變量*********************************/
int k;
/****************************************************************************
函數(shù)功能:端口初始化程序
入口參數(shù):
出口參數(shù):
****************************************************************************/
void port_init (void)
{
   DDRE|=1<<2;
  PORTE|=1<<2;
  DDRA=0XFF;
  PORTA=0XFF;
}
/****************************************************************************
函數(shù)功能:定時(shí)器初始化程序
入口參數(shù):
出口參數(shù):
****************************************************************************/
void timer0_init(void)
{
   TCCR0 = 0x00; //stop
   ASSR  = 0x00; //set async mode
   TCNT0 = 0x3c;
   OCR0  = 0x00;
   TCCR0 = 0x05; //1024分頻
}
/****************************************************************************
函數(shù)功能:定時(shí)中斷服務(wù)程序
入口參數(shù):
出口參數(shù):
****************************************************************************/
#pragma interrupt_handler timer0_ovf_isr:17
void timer0_ovf_isr(void)
{
   TCNT0 = 0x3c;
   k=k+1;
   if(k>150)
   {
   k=0;
   PORTA ^= 0x01;
   }
}
/****************************************************************************
函數(shù)功能:主程序
入口參數(shù):
出口參數(shù):
****************************************************************************/
void main (void)
{
   CLI();     //disable all interrupts
   port_init();
   timer0_init();
   MCUCR = 0x00;
  TIMSK = 0x01;    //T0溢出使能
   SEI();      //enable interrupts   
}

評分

參與人數(shù) 1黑幣 +50 收起 理由
admin + 50 共享資料的黑幣獎(jiǎng)勵(lì)!

查看全部評分

回復(fù)

使用道具 舉報(bào)

您需要登錄后才可以回帖 登錄 | 立即注冊

本版積分規(guī)則

手機(jī)版|小黑屋|51黑電子論壇 |51黑電子論壇6群 QQ 管理員QQ:125739409;技術(shù)交流QQ群281945664

Powered by 單片機(jī)教程網(wǎng)

快速回復(fù) 返回頂部 返回列表