⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 main.c

📁 ht1621 使用例程 驱动段码液晶 同时用诺基亚3310lcd做监控
💻 C
字号:
/***********************************************
***********************************************/   


#include <avr/io.h>
#include <avr/delay.h>
#include <avr/wdt.h>
#include <avr/interrupt.h>
#include <avr/signal.h>
#include "LCD_function.h"
#include "SPI.h"
/******************************************************************************/
/*------宏定义------*/ 
#define uchar         unsigned char 
#define uint          unsigned int 
#define BIT(x)        (1<<(x)) 
#define NOP()         asm("nop") 
#define WDR()         asm("wdr")   

#define WR1      PORTA|=(1<<6)//时钟线
#define WR0      PORTA&=~(1<<6)//时钟线
#define DATA1    PORTA|=(1<<5)//数据线
#define DATA0    PORTA&=~(1<<5)//数据线
#define CS1      PORTA|=(1<<7)//片选线
#define CS0      PORTA&=~(1<<7)//片选线
      
#define data_length 8   //段码液晶数据长度

#define  wait_us(us)\  
    _delay_loop_2((uint16_t)((us)*8/4))


volatile uint data0;           //前16个脉冲存放地址 
volatile uint data1;           //后16个脉冲存放地址 
volatile uint Flag=0;          //接收完成一帧标志位 
volatile float oldFall=0,newFall=0;  //时间的先后纪录 
volatile uint bitcnt=0;        //脉冲个数纪录 

uchar nb,ns,ng,yanchen=0;

uchar table[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

const char   seg_tab[]={0xbf,0x16,0x7d,0x5f,0xd6,0xdb,0xfb,0x1e,0xff,0xdf,//0--9
             /*10*/     0x99,//洁净度第5格、清新、笑脸
			 /*11*/		0xff,//洁净度4格、徽标1、2、3、清新度第1格
             /*12*/     0xf0,//清新度上边4格
             /*13*/     0x9c,//洁净度第5格、清新、哭脸
			 /*14*/		0x9a,//洁净度第5格、清新、无表情
			 /*15*/		0x00,
			 /*16*/		0x10,
             /*17*/		0x30,
			 /*18*/		0x70,
			 /*19*/     0x19,//清新、笑脸
			 /*20*/     0x1c,//清新、哭脸
			 /*21*/		0x1a,//清新、无表情
			 /*22*/		0x81,
			 /*23*/		0xc1,
			 /*24*/		0xe1,
			 /*25*/		0xf1,
             /*26*/		0x10,
			 /*27*/		0x30,
			 /*28*/		0x70,
			 /*29*/     0x29,//标准、笑脸
			 /*30*/		0x2a,//标准、无表情
			 /*31*/     0xac,//洁净度第5格、标准、哭脸
			 /*32*/     0x2c,//标准、哭脸
			 /*33*/     0x49,//强效、笑脸
			 /*34*/		0x4a,//强效、无表情
			 /*35*/     0x4c,//强效、哭脸
			 /*36*/     0xcc,//洁净度第5格、强效、哭脸
			 /*37*/     0x00,
						};
unsigned char disbuff[5] ={0,0,0,0,0};//对应LCD的5位

const char init_tab[]={
	  	   			   0b00000001,//打开系统振荡器命令
      	               0b00000011,//打开LCD偏压发生器命令
     				   0b00000101,//WDT 溢出标志输出失效命令
    				   0b00000110,//时基输出使能命令
    				   0b00011000,//系统时钟源片内RC振荡器命令
    				   0b00101001,//LCD1/3偏压选项4个公共口命令
    				   //0b01000000,//声音频率4KHz命令
    				   //0b00001001,//打开声音输出命令
    				   0b10100000,//时基/WDT 时钟输出1Hz命令
    				   0b10001000 //使/IRQ 输出有效命令
					  };

//***********************************************************************/
void num_do(uint d)
{
nb=d/100;
ns=(d%100)/10;
ng=d%100%10;
}


void DelayMs(uint ms)
{
uint i;
for(i=0;i<ms;i++)
_delay_loop_2(4 *250);
}

void beep(void)
{
 PORTC&=~_BV(0);
 DelayMs(50);
 PORTC|=_BV(0);
 DelayMs(50);
 PORTC&=~_BV(0);
 DelayMs(50);
 PORTC|=_BV(0);
}

void bee(void)
{
 PORTC&=~_BV(0);
 DelayMs(30);
 PORTC|=_BV(0); 
}

void display_init(void)
{

  unsigned char t;
  CS0;
  send_data(0b10000000,3);//送3位命令模式代码100
  for(t=0;t<8;t++)
  {
   send_data(init_tab[t],9);//送9位命令代码 
  }
  CS1;
  WR1;

}

//***********************************************************************/
void display(void)
{

  unsigned char t;
  unsigned char seg_temp;
  
  CS0;
  WR0;
  send_data(0b10100000,3);//送3位“写 ”模式命令代码101
  send_data(0,6);//送6位首地址00h
  for(t=0;t<5;t++)
  {
    seg_temp =seg_tab[disbuff[t]];
  
    send_data(seg_temp,data_length);//向显存送数据
  }
  CS1;
  WR1;

}

//***********************************************************************/

void send_data(unsigned char data_temp,unsigned char loop)
{
  //cli();
  for(;loop!=0;loop--)
  {
    wait_us(1);
    WR0;
    wait_us(1);
  if((data_temp&0b10000000)==0)
  {
    DATA0;
  }
  else
  {
    DATA1;
  }
    data_temp=(data_temp<<1);
    WR1;
  }
  //sei();
}


void timer1_init(void) 
{ 
        TCCR1B = 0x00;//停止定时器 
        TIMSK |= 0x20;//中断允许 
        ICR1H  = 0xFd; 
        ICR1L  = 0xFd;//输入捕捉匹配值 
        TCCR1A = 0x00; 
		TCCR1B = 0x83;//启动定时器 
} 


void init_devices(void) 
{ 
        cli(); //禁止所有中断  
        timer1_init();
        MCUCR |= _BV(ISC01); 
        GICR |= (1<<INT0);

         //TCNT0=0; // T/C0 开始值
        // TCCR0=_BV(CS02)|_BV(CS00); // 预分频 ck/1024 ,计数允许
        // TIMSK=_BV(TOIE0); //T/C0 中断允许

        sei();//开全局中断 
}

int main(void) 
{
     unsigned char s0=37,s1=37,s2=30,s3=37,s4=37,v1=0,v2,v3=0,v0,v,dst;
	 float v00,y;
	 uchar x=0xb0,time=0,on=1,dust=0,t;
	                                
     IO_init();
	 PORTA&=~_BV(0);
	 DDRA&=~_BV(0);

	 PORTA&=~_BV(2);
	 DDRA&=~_BV(2);
     PORTA&=~_BV(3);

	 PORTD|=_BV(2);
	 DDRD&=~_BV(2);

	 PORTD&=~_BV(6);
	 DDRD&=~_BV(6);
     
	 DelayMs(100);

	 PORTC&=~_BV(7);
	 PORTC&=~_BV(6);
	  
     init_devices();
	 display_init();
	 InitSPI();
	 LCD_init();

	 ADC_init();
   	LCD_clear();
      
	    LCD_write_english_string(0,0,"<-----ADC---->");
    	LCD_write_english_string(0,1,"ADC_0=");
		LCD_write_english_string(3,3,"irDA_RC5 Mode");
		LCD_write_english_string(0,4,"irDA_Code=00");
	 
	 
	 disbuff[0] =s0;
     disbuff[1] =s1;
	 disbuff[2] =s2;
     disbuff[3] =s3;
     disbuff[4] =s4;  
	 display();
     wdt_enable(WDTO_250MS);

while(1)
{
 if(y<5000) y++;
 else
  {
   y=0;
   dust=yanchen;
   yanchen=0;
   }
    wdt_reset();
	
	disbuff[0] =s0;
    disbuff[1] =s1;
	disbuff[2] =s2;
    disbuff[3] =s3;
    disbuff[4] =s4;
    display();
	v0=get_ad0();
    v=v0/51;
	v00=v0/5.1;
    num_do(v00);
    LCD_set_XY(36,1);
    LCD_write_char(table[ns]);
	LCD_set_XY(42,1);
    LCD_write_char('.');
	LCD_set_XY(45,1);
    LCD_write_char(table[ng]);
	LCD_set_XY(51,1);
	LCD_write_char('v');

    num_do(v0);
	LCD_set_XY(66,1);
    LCD_write_char(table[nb]);
	LCD_set_XY(72,1);
    LCD_write_char(table[ns]);
	LCD_set_XY(78,1);
    LCD_write_char(table[ng]);

	num_do(dust);
	LCD_set_XY(0,5);
    LCD_write_char(table[nb]);
	LCD_set_XY(6,5);
    LCD_write_char(table[ns]);
	LCD_set_XY(12,5);
    LCD_write_char(table[ng]);

	num_do(yanchen);
	LCD_set_XY(20,5);
    LCD_write_char(table[nb]);
	LCD_set_XY(26,5);
    LCD_write_char(table[ns]);
	LCD_set_XY(32,5);
    LCD_write_char(table[ng]);

	num_do(dst);
	LCD_set_XY(40,5);
    LCD_write_char(table[nb]);
	LCD_set_XY(46,5);
    LCD_write_char(table[ns]);
	LCD_set_XY(52,5);
    LCD_write_char(table[ng]);

	LCD_set_XY(72,4);
	LCD_write_char(table[((x&0xf0)>>4)]);
	LCD_set_XY(78,4);
	LCD_write_char(table[x&0x0f]);

	LCD_set_XY(60,4);
	LCD_write_char(table[((t&0xf0)>>4)]);
	LCD_set_XY(66,4);
	LCD_write_char(table[t&0x0f]);
/*********************************************************************/
   if(dust<=5) dst=1;
   if((dust>=6)&(dust<=12)) dst=2;
   if((dust>=13)&(dust<=18)) dst=3;
   if((dust>=19)&(dust<=25)) dst=4;
   if(dust>=26) dst=5;
   	          
if(Flag) 
   { 
    Flag=0;  //清除标志位
	bitcnt=0;   //计数标志位清0 
	t=(uchar)((data1&0xff00)>>8);
	if((t!=0x60)&(t!=0xd0)&(t!=0xe0)&(t!=0x10)&(t!=0x70)&(t!=0x88)&(t!=0x68)) 
	{
	 x=t;
	 bee();
	 }
    }
if(t==0xe0)//定时
  {
   bee();
   if(time!=40) time+=5;
   else time=0;
   s0=time/10;
   s1=time%10;
   t=0;
  }
if((x==0x50)&(on==1))//关机
  {
   s0=s1=s2=s3=s4=37;
   PORTA&=~_BV(4);
   on=0;
   beep();
  }
if((t==0xd0)&(on==0))//开机
  {
    beep();
    DelayMs(5000);
  }
/***********段码液晶******************************/ 

 switch (x)
  {
   case 0x90 :
   {  
	switch (v)
	{
	case 1:{
	        switch(dst)
			{
			 case 1:{s2=19,s3=22,s4=15;}break;
			 case 2:{s2=19,s3=23,s4=15;}break;
			 case 3:{s2=21,s3=24,s4=15;}break;
			 case 4:{s2=20,s3=25,s4=15;}break;
			 case 5:{s2=13,s3=25,s4=15;}break;
			 }
			}break;

	case 2:{
	        switch(dst)
			{
			 case 1:{s2=19,s3=22,s4=26;}break;
			 case 2:{s2=19,s3=23,s4=26;}break;
			 case 3:{s2=21,s3=24,s4=26;}break;
			 case 4:{s2=20,s3=25,s4=26;}break;
			 case 5:{s2=13,s3=25,s4=26;}break;
			 }
	       }break;

	case 3:{
            switch(dst)
			{
			 case 1:{s2=21,s3=22,s4=27;}break;
			 case 2:{s2=21,s3=23,s4=27;}break;
			 case 3:{s2=21,s3=24,s4=27;}break;
			 case 4:{s2=20,s3=25,s4=27;}break;
			 case 5:{s2=13,s3=25,s4=27;}break;
			 }
	       }break;

	case 4:{
            switch(dst)
			{
			 case 1:{s2=20,s3=22,s4=28;}break;
			 case 2:{s2=20,s3=23,s4=28;}break;
			 case 3:{s2=20,s3=24,s4=28;}break;
			 case 4:{s2=20,s3=25,s4=28;}break;
			 case 5:{s2=13,s3=25,s4=28;}break;
			 }
	        }break;

	case 5:{
	        switch(dst)
			{
			 case 1:{s2=20,s3=22,s4=12;}break;
			 case 2:{s2=20,s3=23,s4=12;}break;
			 case 3:{s2=20,s3=24,s4=12;}break;
			 case 4:{s2=20,s3=25,s4=12;}break;
			 case 5:{s2=13,s3=25,s4=12;}break;
			 }
			}break;
    }

  }break;
  case 0xB0:
   {
	switch (v)
	{
	case 1:{
	        switch(dst)
			{
			 case 1:{s2=29,s3=22,s4=15;}break;
			 case 2:{s2=29,s3=23,s4=15;}break;
			 case 3:{s2=30,s3=24,s4=15;}break;
			 case 4:{s2=32,s3=25,s4=15;}break;
			 case 5:{s2=31,s3=25,s4=15;}break;
			 }
			}break;

	case 2:{
	        switch(dst)
			{
			 case 1:{s2=29,s3=22,s4=26;}break;
			 case 2:{s2=29,s3=23,s4=26;}break;
			 case 3:{s2=30,s3=24,s4=26;}break;
			 case 4:{s2=32,s3=25,s4=26;}break;
			 case 5:{s2=31,s3=25,s4=26;}break;
			 }
	       }break;

	case 3:{
            switch(dst)
			{
			 case 1:{s2=30,s3=22,s4=27;}break;
			 case 2:{s2=30,s3=23,s4=27;}break;
			 case 3:{s2=30,s3=24,s4=27;}break;
			 case 4:{s2=32,s3=25,s4=27;}break;
			 case 5:{s2=31,s3=25,s4=27;}break;
			 }
	       }break;

	case 4:{
            switch(dst)
			 {
			 case 1:{s2=32,s3=22,s4=28;}break;
			 case 2:{s2=32,s3=23,s4=28;}break;
			 case 3:{s2=32,s3=24,s4=28;}break;
			 case 4:{s2=32,s3=25,s4=28;}break;
			 case 5:{s2=31,s3=25,s4=28;}break;
			 }
	        }break;

	case 5:{
	        switch(dst)
			{
			 case 1:{s2=32,s3=22,s4=12;}break;
			 case 2:{s2=32,s3=23,s4=12;}break;
			 case 3:{s2=32,s3=24,s4=12;}break;
			 case 4:{s2=32,s3=25,s4=12;}break;
			 case 5:{s2=31,s3=25,s4=12;}break;
			 }
			}break;
    }
  }break;
   case 0xf0:
   
   {
  
	switch (v)
	{
	case 1:{
	        switch(dst)
			{
			 case 1:{s2=33,s3=22,s4=15;}break;
			 case 2:{s2=33,s3=23,s4=15;}break;
			 case 3:{s2=34,s3=24,s4=15;}break;
			 case 4:{s2=35,s3=25,s4=15;}break;
			 case 5:{s2=36,s3=25,s4=15;}break;
			 }
			}break;

	case 2:{
	        switch(dst)
			{
			 case 1:{s2=33,s3=22,s4=26;}break;
			 case 2:{s2=33,s3=23,s4=26;}break;
			 case 3:{s2=34,s3=24,s4=26;}break;
			 case 4:{s2=35,s3=25,s4=26;}break;
			 case 5:{s2=36,s3=25,s4=26;}break;
			 }
	       }break;

	case 3:{
            switch(dst)
			{
			 case 1:{s2=34,s3=22,s4=27;}break;
			 case 2:{s2=34,s3=23,s4=27;}break;
			 case 3:{s2=34,s3=24,s4=27;}break;
			 case 4:{s2=35,s3=25,s4=27;}break;
			 case 5:{s2=36,s3=25,s4=27;}break;
			 }
	       }break;

	case 4:{
            switch(dst)
			{
			 case 1:{s2=35,s3=22,s4=28;}break;
			 case 2:{s2=35,s3=23,s4=28;}break;
			 case 3:{s2=35,s3=24,s4=28;}break;
			 case 4:{s2=35,s3=25,s4=28;}break;
			 case 5:{s2=36,s3=25,s4=28;}break;
			 }
	        }break;

	case 5:{
	        switch(dst)
			{
			 case 1:{s2=35,s3=22,s4=12;}break;
			 case 2:{s2=35,s3=23,s4=12;}break;
			 case 3:{s2=35,s3=24,s4=12;}break;
			 case 4:{s2=35,s3=25,s4=12;}break;
			 case 5:{s2=36,s3=25,s4=12;}break;
			 }
			}break;
    }

   }break;

 
   }  
 }
  
}
/*****************************************************/
//数据头的时间:Th=9+4.5=13.5ms 
//数据“0”的时间:T0=0.565+0.56=1.125ms 
//数据“1”的时间:T1=1.685+0.56=2.245ms 
//定时器T1输入捕捉中断服务程序 
SIGNAL(SIG_INPUT_CAPTURE1)
{        
        //timer 1 input capture event, read (int)value in ICR1 using; 
        // value=ICR1L;            //Read low byte first (important) 
        // value|=(int)ICR1H << 8; //Read high byte and shift into top byte 
        // TIFR|=BIT(ICF1);//软件写1清中断标志 
        float time=0; 
        unsigned int temp=0; 
        newFall=ICR1;         //读取当前时间 
        time=newFall-oldFall; //计算脉冲加间隔的时间 
        oldFall=newFall;      //存放上一次的时间 
        if(time<0)  time=newFall-oldFall+0xffff;  //定时周期交叉的情况 
         temp=(unsigned int)time; //取整 
        //T0的8分频,即(1.125*1000)/8 = 140.625us ;正负20宽范围判断 
        if((temp>20) && (temp<200)) // "0"信号 
        { 
            temp=0; 
        } 
        //T1的8分频为280.625us 
        else if((temp>200) && (temp<400)) //“1”信号 
        {
            temp=1; 
        } 
        //Th的8分频为1687.5us 
        else if((temp>1300) && (temp<2200)) //header头信号 
        { 
                bitcnt=0; 
                data0=0; 
                data1=0; 
				 
                return; //返回,等待下次开始接收 
        } 
        else //干扰信号 
        { 
            bitcnt=0; 
                data0=0; 
                data1=0; 
            return; 
        }
		 
        bitcnt++;
		
        if(bitcnt<16) //开始接收前16位 
        { 
            data0=data0|temp; 
                data0=data0<<1;
				
				
        } 
        else if(bitcnt==16) 
        { 
            data0=data0|temp;
			
			
        } 
        else if(bitcnt<32) //开始接收后16位 
        { 
            data1=data1|temp; 
            data1=data1<<1; 
			
        } 
        else if(bitcnt==32) //接收完最后一位 
        { 
           data1=data1|temp; 
           Flag=1;       //接收完一帧,标志位置1
        }
}

 
SIGNAL(SIG_INTERRUPT0) //int0 interrupt
{
 yanchen++;  
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -