搜索
bottom↓
回复: 25

献丑,第一次做AVR;感温18B20+MC14489驱动LED数码管显示

[复制链接]

出0入0汤圆

发表于 2007-9-28 22:27:44 | 显示全部楼层 |阅读模式
/*****************************************************
这是用18B20测温度的程式,用MC14489驱动LED数码管显示,
这里只是程式的一部分,已经测试过,可以正确的显示,串口部分
可以用串口调试软件来测试,程式并没有完善好,尚有一些问题没有修改。
由于本人是刚刚学的AVR,从OURAVR学了不少知识,把这部分拿出来献丑了。

软件:CodeVisionAVR
人物:EvanL

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

#include<mega8515.h>
#include<delay.h>
#include<stdio.h>
#include<math.h>

#include <1wire.h>
#include<ds18b20.h>    // DS1820 Temperature Sensor functions

/*************************************************************/
// 1 Wire Bus functions
#asm
   .equ __w1_port=0x15;PORTC   //PC3 1 Wire Device(DS18B20)input
   .equ __w1_bit=3             //18B20端口设置,由于18B20是双向输入输出
#endasm                           
/**********************************************************/                              
  
#define uchar unsigned char
#define uint unsigned int

#define DATA  PORTC.4      //MC14489的数据端;
#define CLK   PORTC.2      //MC14489的时钟端;
#define ENA   PORTC.0      //MC14489的使能端;
#define MAX_DEVICES 8   
        

/*****************************************************************/
/*串口代码,发送,波特率9600,这段代码是由CVAVR自己产生的*/
/*****************************************************************/
#define RXB8 1
#define TXB8 0
#define UPE 2
#define OVR 3
#define FE 4
#define UDRE 5
#define RXC 7

#define FRAMING_ERROR (1<<FE)
#define PARITY_ERROR (1<<UPE)
#define DATA_OVERRUN (1<<OVR)
#define DATA_REGISTER_EMPTY (1<<UDRE)
#define RX_COMPLETE (1<<RXC)

// USART Transmitter buffer
#define TX_BUFFER_SIZE 8
char tx_buffer[TX_BUFFER_SIZE];

#if TX_BUFFER_SIZE<256
unsigned char tx_wr_index,tx_rd_index,tx_counter;
#else
unsigned int tx_wr_index,tx_rd_index,tx_counter;
#endif

// USART Transmitter interrupt service routine
interrupt [USART_TXC] void usart_tx_isr(void)
{
if (tx_counter)
   {
   --tx_counter;
   UDR=tx_buffer[tx_rd_index];
   if (++tx_rd_index == TX_BUFFER_SIZE) tx_rd_index=0;
   };
}

#ifndef _DEBUG_TERMINAL_IO_
// Write a character to the USART Transmitter buffer
#define _ALTERNATE_PUTCHAR_
#pragma used+

// Standard Input/Output functions
void putchar(char c)
{
while (tx_counter == TX_BUFFER_SIZE);
#asm("cli")
if (tx_counter || ((UCSRA & DATA_REGISTER_EMPTY)==0))
   {
   tx_buffer[tx_wr_index]=c;
   if (++tx_wr_index == TX_BUFFER_SIZE) tx_wr_index=0;
   ++tx_counter;
   }
else
   UDR=c;
#asm("sei")
}
#pragma used-
#endif

/*******************************************************************/
            
uchar ds18b20_devices;        
            //number of DS1820 devices connected to the 1 Wire bus
uchar rom_code[MAX_DEVICES][9]; //DS18B20 devices ROM code storage area

uchar num1,num2,num3,num4;
uchar numds1,numds2,numds3,numds4;      //4bit 7segment code number;
uchar DS1,DS2,tmpd1,tmpd2,num_devices;
void DSPDATA(uchar DSCMD, uchar DSDATA1, uchar DSDATA2);
void DSPCMD(uchar CMD);
void DS18B20_cfg(void);   
                //Search DS18B20 Device and Configure each DS18B20 device;
void measure_temp(void);
void float_7seg(float number);  
void putchar(char c);

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

void main(void)
{   


   
     SREG.7=0;       //Global disable interrupts
     
     PORTC=0x00;
     DDRC=0x15;
   
     MCUCR=0x00;
     EMCUCR=0x00;
     
     UCSRA=0x00;
     UCSRB=0x48;
     UCSRC=0x86;
     UBRRH=0x00;
     UBRRL=0x19;
     
     CLK=0;
     DATA=0;
     ENA=1;  
     
   
     
     WDTCR=0x1B;
     WDTCR=0x0B;

     SREG.7=1;
     
    // w1_init();       // 1 Wire Bus initialization
    // DS18B20_cfg();   // DS18B20 Config
   
   while(1)
     {
        #asm
        WDR
        #endasm
        
        #asm("sei")
        
/*****************************************************
这一段18B20加载的,目前放在循环里,原来是在循环上面的。不知道怎么回事,
用在M8515上如果在工作时增加或减少18B20时,会出现乱码,而用在M168上时就
不会出现这个现象。
***********************************************************************/
   
     w1_init();       // 1 Wire Bus initialization

     DS18B20_cfg();   // DS18B20 Config
/********************************************************************/

   
       if(ds18b20_devices==0)
       {
       DSPCMD(0xff);   
       DSPDATA(0x86,0x7d,0x00);
       }
       else
       {
          measure_temp();
       }                        
   
      }
   
}      

void float_7seg(float number)
           //float number converter to 4 bit 7segment number
{
         uchar k1;   
         k1=number;
         num4=(number-k1)*10;         
         num3=(k1%10);         
         k1=k1/10;
         num2=k1%10;
         num1=k1/10;              
}


//----------------------------------------------------------------------------------------------------------
void DS18B20_cfg(void)      
         //Search DS18B20 Device and Configure each DS18B20 device;
{  
   uchar i;
   // detect how many DS18B20 devices are connected to the 1 Wire bus
   ds18b20_devices=w1_search(DS18B20_SEARCH_ROM_CMD,rom_code);  
  
   // configure each DS18B20 device for 12 bit temperature measurement resolution
   for (i=0;i<ds18b20_devices;)
     ds18b20_init(&rom_code[i++][0],20,30,DS18B20_12BIT_RES);
}

void measure_temp(void)   
{
   uchar i,j;
   float n;
   
   
   if(ds18b20_devices)   
      for (i=0;i<ds18b20_devices;i++)
      {
        n=ds18b20_temperature(&rom_code[0]);        
      
       float_7seg(n);
        
       numds1=num1;
       numds2=num2;
       numds3=num3;
       numds4=num4;
        
       num4&=0x0f;
       num3=num3<<4;
       num3&=0xf0;
       DS2=num3|num4;
      
      
       num2&=0x0f;
       num1=num1<<4;
       num1&=0xf0;
       DS1=num1|num2;
        
        //每个温度值显示时指明是第几个18B20;
        j=i+1;
        j=0x0f&j;
        num_devices=0x00|j;
        num_devices=num_devices|0xa0;
        
        // MC14489驱动数码管显示;  
      

       DSPCMD(0x91);   
       DSPDATA(num_devices,DS1,DS2);
       delay_ms(100);
      
       numds2=numds2<<4;
       numds2&=0xf0;
       numds3&=0x0f;
       tmpd1=numds2|numds3;
     
       numds1=numds4<<4;
       numds1&=0xf0;      
       tmpd2=numds1|0x0c;
       printf("TEMP%2x:%2x.%2x\n\r",num_devices,tmpd1,tmpd2);// TO PC,RS232;      
  }
}         

/*************MC14489驱动代码************************************/
  
void DSPCMD(uchar CMD)

{  //单字节命令函数, 写入MC14489内部设置寄存器
  
  uchar i;
  ENA=0;                  // 使能MC14489
  for (i=8;i>=1;i--) {    // 写入单字节命令
    DATA=CMD&0x80;
    CMD=CMD<<1;
    CLK=0;
    CLK=1;
  }
  ENA=1;                  // 禁止MC14489
}

void DSPDATA(uchar DSCMD, uchar DSDATA1, uchar DSDATA2)
{
  uchar DSP,i,j;          // 多字节命令函数, 写入MC14489显示寄存器
  i=0;
  ENA=0;                  // 使能MC14489
  while(i<24) {           // 写入三字节显示数据
   if(i<8) {DSP=DSCMD;}
    else if(i<16) {DSP=DSDATA1;}
     else {DSP=DSDATA2;}
     for(j=8;j>=1;j--) {
       DATA=DSP&0x80;
       DSP=DSP<<1;
       CLK=0;
       CLK=1;
     }
     i=i+8;
  }
  ENA=1;                  //禁止MC14489      
}

出0入0汤圆

 楼主| 发表于 2007-9-28 22:30:53 | 显示全部楼层
沙发,自己坐,呵呵,公司没有条件上网,只有晚上才有空来逛逛。

出0入0汤圆

发表于 2007-9-29 10:52:34 | 显示全部楼层
能不能发个原理图,好东西大家共享。

出0入0汤圆

发表于 2007-9-29 15:12:06 | 显示全部楼层
麻烦搂主能不能将原理说个先,谢谢

出0入0汤圆

发表于 2007-9-29 16:46:53 | 显示全部楼层
是啊,发个原理图么

出0入0汤圆

 楼主| 发表于 2007-9-29 20:13:05 | 显示全部楼层
没有画原理图,就是根据元件资料在万用板上跳线做出来的,其实都很简单,就是搭积木。

出0入0汤圆

 楼主| 发表于 2007-9-29 20:20:00 | 显示全部楼层
//部分说明:
/***************************************/
       #asm
        WDR
        #endasm  //开看门狗;
         
        #asm("sei")  //开中断;


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

       if(ds18b20_devices==0)
       {
       DSPCMD(0xff);     
       DSPDATA(0x86,0x7d,0x00); //MC14489的显示值,具体资料网上都有,自己找吧。
       }
       else
       {
          measure_temp();
       }                          
     
      }  
//主程序,判断是否有感温头,如果没有,数码管显示“no—”,如果有做“measure_temp(); ”内容,显示温度和发送到PC上。

出0入0汤圆

 楼主| 发表于 2007-9-29 20:30:46 | 显示全部楼层

出0入0汤圆

发表于 2007-9-30 08:14:43 | 显示全部楼层
跳这么多线啊,高人啊

出0入0汤圆

 楼主| 发表于 2007-10-1 15:34:43 | 显示全部楼层
程式贴上来时没有加上报警部分,另外零下时显示会出错,没有做“-”处理,其他部分是没有问题的。

关于跳线,这些跳线不是一次跳出来的,想要用哪部分时就跳哪部分,虽然看起来乱,但在我心中是不乱的,怕乱的就在IC上贴上注释。

出0入0汤圆

发表于 2007-10-1 15:40:12 | 显示全部楼层
to:evanl
你在板厂上班呀,这样打板。
有在板厂上班的不,多打些这样的板出来,我很想要几片(付费)。

出0入0汤圆

发表于 2007-10-1 18:59:18 | 显示全部楼层
14489没有停产吗?以前记得很不好买到的。

出0入0汤圆

发表于 2007-10-1 19:19:37 | 显示全部楼层
nb得一塌糊涂

出0入0汤圆

 楼主| 发表于 2007-10-3 16:42:53 | 显示全部楼层
回10楼,我不是在做PCB的厂工作,这是因为公司有这样的条件,PCB厂家给我们做样是免费的。

这个试验板目前我没有了,过一段时间我把AVR常用的整合到里面去,重新做块万用试验板,到时可能会多几片,苏州的到时倒可以给的,外地的我就照顾不了了,还有如果到时有的话我会发贴的,也不会要钱的。以后的事情还是以后再说吧。

出0入0汤圆

发表于 2007-10-8 15:29:44 | 显示全部楼层
"没有画原理图,就是根据元件资料在万用板上跳线做出来的,其实都很简单,就是搭积木。"
我想请问楼主,你搭积木之前不先做原理图么,如果是这样,你就不怕出错么?

出0入0汤圆

 楼主| 发表于 2007-10-8 20:34:27 | 显示全部楼层
回14楼,我在跳线做试验板子时,先查芯片的资料,用笔画个草图,确定引脚定义及连接,然后焊接板子。一般来讲,如果要在万用板上跳线做试验板,肯定要心中有数自己在做什么,怎么搭接,至于怎么焊接会不会焊错,那就是焊接的水平和心细等问题了。

出0入0汤圆

发表于 2007-10-9 11:34:09 | 显示全部楼层
楼主,给你一个建议,无论在什么时候最好要先做好原理图,这是方法问题.

出0入0汤圆

发表于 2007-10-9 12:01:56 | 显示全部楼层
真是服了!

出0入0汤圆

发表于 2007-10-9 14:50:39 | 显示全部楼层
看电路板背面我晕了!!!牛人啊!!!

出0入0汤圆

发表于 2007-10-10 14:29:42 | 显示全部楼层
这个线!!!
我倒了

出0入0汤圆

 楼主| 发表于 2007-10-11 20:20:26 | 显示全部楼层
呵呵,把这块试验板照片放到网上,本来也就给大家看看我做的温度测试情况,没想到竟然也让大家佩服,谢谢!不过也可见,我动手能力强了一点点,但编程能力还是差的很多了,看来还是要多多努力啊!

出0入0汤圆

发表于 2007-10-15 16:58:22 | 显示全部楼层
你就吹吧
头像被屏蔽

出0入0汤圆

发表于 2007-10-15 21:58:49 | 显示全部楼层
【21楼】 wx21cen 不服气可以上传些更有用的资料

我们这里鼓励大家共享与交流,如果楼主的资料有缺陷,请指出来,而不是说这类让人感到困惑的话。

出0入0汤圆

 楼主| 发表于 2007-10-19 09:02:17 | 显示全部楼层
呵呵,阿莫站长就别指责 wx21cen 了,我和他相识,他对我还是比较了解的,这么说还是可以理解的。

在MCU领域包括AVR他也算高人一个了,不过他算是那种只潜不顶的了。^_^

出0入0汤圆

发表于 2007-11-3 15:52:05 | 显示全部楼层

出0入0汤圆

发表于 2011-8-16 15:26:22 | 显示全部楼层
mark,这段程序似曾相识
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-5-7 15:39

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表