ATMEGA128相关例程
自己学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
uchart;
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
t++;
if(cnt==255)
t=0;
}
void main()
{
//DDRB=0XFF;
SREG|=0X80;
TIMSK=0X04;
timer1_init();
while(1)
{;
}
}
2、AD转换+数码管显示
/***************************************************************************/
/*ADC测试程
序 */
/*目标器件:ATmega128 */ /*晶振:RC
8MHZ */
/*编译环境:ICCAVR 7.13A */ /*E-Mail:number007cool163.
*/
/*时间: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)