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 */
//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 */
/*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
}
|