专注电子技术学习与研究
当前位置:单片机教程网 >> MCU设计实例 >> 浏览文章

avr单片机驱动max7219的程序

作者:huqin   来源:本站原创   点击数:  更新时间:2014年02月17日   【字体:


 #include<iom16v.h>
#include<macros.h>

#define uchar unsigned char
#define uint unsigned int
//定义输出io口
#define Y1_OUT DDRC|=BIT(5);
#define Y1_H PORTC|=BIT(5);  
#define Y1_L PORTC&=~BIT(5);
#define Y2_OUT DDRD|=BIT(6);
#define Y2_H PORTD|=BIT(6);  
#define Y2_L PORTD&=~BIT(6); 
#define Y3_OUT DDRD|=BIT(7);
#define Y3_H PORTD|=BIT(7);  
#define Y3_L PORTD&=~BIT(7);
#define Y4_OUT DDRB|=BIT(0);
#define Y4_H PORTB|=BIT(0);  
#define Y4_L PORTB&=~BIT(0);
#define Y5_OUT DDRC|=BIT(4);
#define Y5_H PORTC|=BIT(4);  
#define Y5_L PORTC&=~BIT(4);
#define Y6_OUT DDRB|=BIT(1);
#define Y6_H PORTB|=BIT(1);  
#define Y6_L PORTB&=~BIT(1);
//ad求平均的个数
#define N  3 
//数码管亮度调节0x00-0xff
#define P  0x01
uint t1,t2,t3,t4,tt1,tt2,tt3,tt4;
uint addata,adc;
uchar g1,g2,g3,g4;
////////////////////////////////////////////////////////////////////////////////
void port_init()
{
   DDRC&=BIT(0)&BIT(1)&BIT(2)&BIT(3); //AD转换口设置为输入、无上拉
   PORTC&=BIT(0)&BIT(1)&BIT(2)&BIT(3);
    
   DDRD|=0x3f;
   PORTD|=0x3f;          //配置PD口为输入,有上拉电阻
   DDRD&=0xC0;
  
    //Y1_OUT;Y2_OUT;Y3_OUT;Y4_OUT;Y5_OUT;Y6_OUT;
  // Y1_H;Y2_H;Y3_H;Y4_H;Y5_H;Y6_H;
}
//spi初始化/////////////////////////////////////////////////////////////////////
void spi_init()
{
        DDRB|=BIT(2)|BIT(3)|BIT(5);//置spi数据口为输出
        SPCR=0x51;
        PORTB|=BIT(2);
        SPSR&=0x7f;
}
//初始化max7219数码管模块////////////////////////////////////////////////////////
void initmax7219()
{
       spi_init();
        max7219(0x0c,0x00);   //掉电模式:0,普通模式:1
        max7219(0x09,0xff);   //译码方式:BCD码
        max7219(0x0a,P);      //亮度调节
        max7219(0x0b,0x07);   //扫描界限;4个数码管显示
        max7219(0x0c,0x01);   //掉电模式:0,普通模式:1
        max7219(0x0f,0x00);   //显示测试:1;测试结束,正常显示:0
        delay_ms(100);
}
//定时器1初始化子程序///////////////////////////////////////////////////////////
void init_timer1()
{
  TCCR1B|=0x04;//256分频
  TCNT1H=0xff;//高8位初值
  TCNT1L=0x03;//低8位初值
  TIMSK|=BIT(2);//定时器1的中断使能
}
//定时器0初始化子程序///////////////////////////////////////////////////////////
void init_timer0()
{
  TCCR0|=0x04;//256分频
  TCNT0=0x00;//初值
  TIMSK|=BIT(0);//定时器0的中断使能
}
//延时函数//////////////////////////////////////////////////////////////////////
void delay_ms(uint i)
{
    while(i--)
    {                         
   uint j;               
        for(j=1;j<=1332;j++);              
    }
}
//向max7219写入地址和数据///////////////////////////////////////////////////////
void max7219(uchar add,uchar date)
{
  PORTB&=~BIT(2);
  SPDR=add;
  while(!(SPSR&0x80));
  add=SPSR;//读取SPSR来清除SPIF;
  SPDR=date;
  while(!(SPSR&0x80))
  date=SPSR;
  PORTB|=BIT(2);
}
//ADC单次转换子程序带1个参数,1个返回值/////////////////////////////////////////
int Mega8_ad(uchar chl)
{
     uint sum = 0;
     uchar count;
     ADMUX=0x00;            //采用外部参考电压,输出数据右对齐
     ADMUX|=chl;            //设置指定的通道
     ADCSR=0x80;        //使能adc采用单次转换,查询模式,     
     ADCSR|=BIT(1)|BIT(0);  //8分频
 for(count=0;count<N;count++)
        {
  ADCSR|=BIT(6);     //启动转换
           while(!(ADCSR&(BIT(ADIF))));  //等待转换结束
           addata=ADCL;     //读取低8位数据
           addata+=ADCH*256; //读取高2位数据
           adc=addata/10.24;
           sum=sum+adc;
           delay_ms(1);
         }
           return (sum/N);
 }
//切换ADC通道采集四个电位器的值送数码管显示//////////////////////////////////////
void adc_max7219()
{
   uchar shi1=0, ge1=0;                    //定义2个局部变量
t1=Mega8_ad(0X40);                        //选择PA0为AD通道,将转换结果赋给t1
     max7219(2,t1/10); max7219(1,t1%10);
  delay_ms(2);
t2=Mega8_ad(0X41);
     max7219(4,t2/10);max7219(3,t2%10);
delay_ms(2);
 
t3=Mega8_ad(0X42);
     max7219(6,t3/10);max7219(5,t3%10);
delay_ms(2);
t4=Mega8_ad(0X43);
     max7219(8,t4/10);max7219(7,t4%10);
delay_ms(2); 
}
//主函数////////////////////////////////////////////////////////////////////////
void main()
{
    port_init();       //初始化io
initmax7219();     //初始化max7219
    //init_timer0();     //初始化定时器0
    init_timer1();     //初始化定时器1
    SREG|=BIT(7);      //打开总中断
   Mega8_ad(0X40);  //启动一次通道0的AD转换
   Mega8_ad(0X41);  //启动一次通道1的AD转换
   Mega8_ad(0X42);  //启动一次通道2的AD转换
   Mega8_ad(0X43);  //启动一次通道3的AD转换

        while(1)
        { 
adc_max7219();
///////////////////////////////////////////////////////////////////////////////
if(!(PIND&BIT(1)))//启动按钮
   { 
    delay_ms(10);
if(!(PIND&BIT(1)))//启动按钮
      {
       while(!(PIND&BIT(1)));
  Y1_OUT;Y1_L;g1=1;
      }
  } 
 
if(!(PIND&BIT(2)))//停止按钮
     {
     Y1_OUT;Y1_H;
Y2_OUT;Y2_H;
Y3_OUT;Y3_H;
Y4_OUT;Y4_H;
g1=0;g2=0;g3=0;g4=0;
tt1=0;tt2=0;tt3=0;tt4=0;
      }
 

if(t3<tt3)//工作模式判断///车CD纹///高光
 {
    if(!(PIND&BIT(3))){ g1=0;tt3=0;Y1_OUT;Y1_H;}
   // else
//{
if(!(PIND&BIT(4))){g1=0;tt3=0;Y2_OUT;Y2_L;}
//}
 }
 
if(!((PIND&BIT(5))|(PIND4&BIT(4)))) g2=1;//行程开关
 
if(t2<tt2){g2=0;tt2=0;Y1_OUT;Y1_H;g3=1;}
 
if(t1<tt1){g3=0;tt1=0;Y2_OUT;Y2_H;}
 
/////////////////////////////////////////////////////////////////////////////// 
 
    
      
        }
}

//定时器0的中断程序////刷新AD转换的值和刷新数码管用/////////////////////////////
#pragma interrupt_handler timer0:10
void timer0(void)
{
TCNT0=0X00;
}
//定时器1的中断程序///给继电器定时用////////////////////////////////////////////
#pragma interrupt_handler timer1:9
void timer1(void)
{
TCNT1H=0xff;
TCNT1L=0x03;
if(g1)tt3++;
if(g2)tt2++;
if(g3)tt1++;
}
 

关闭窗口

相关文章