找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
查看: 3419|回复: 2
打印 上一主题 下一主题
收起左侧

谁能给帮忙把这个程序分解下谢谢。数码管实在搞不亮

[复制链接]
跳转到指定楼层
楼主


#include "p18cxxx.h"              //头文件
#include "delays.h"
#include "SEG.h"
#define uchar unsigned char
#define uint unsigned int
#define  uch unsigned char                     //给unsigned char起别名 uch
# define DQ  LATAbits.LATA0                              //定义18B20数据端口
# define DQ_DIR TRISAbits.TRISA0                         //定义18B20D口方向寄存器
# define DQ_HIGH()  DQ =1 ; DQ_DIR =1                  //设置数据口为输入
# define DQ_LOW()    DQ_DIR = 0 ;DQ = 0        //设置数据口为输出
unsigned char  TLV=0 ;                        //采集到的温度高8位
unsigned char  THV=0;                         //采集到的温度低8位
unsigned char TZ=0;                           //转换后的温度值整数部分
unsigned char TX=0;                           //转换后的温度值小数部分
unsigned int wd;                              //转换后的温度值BCD码形式
unsigned char shi;                             //整数十位
unsigned char ge;                              //整数个位
unsigned char shifen;                          //十分位
unsigned char baifen;                          //百分位
unsigned char qianfen;                         //千分位
unsigned char wanfen;                          //万分位
#define TMR0HLOAD     0xf6        //4MHZ  2.5mS
#define TMR0LLOAD     0x4D
unsigned char TickClock = 0;      //系统时基

#define SCLK   LATBbits.LATB0     //74HC164时钟
#define SDAT   LATBbits.LATB1     //74HC164数据
const unsigned char SegCode[] =   //图型表
{
    Bmp0Map,Bmp1Map,Bmp2Map,Bmp3Map,Bmp4Map,Bmp5Map,
    Bmp6Map,Bmp7Map,Bmp8Map,Bmp9Map,BmpAMap,BmpBMap,
    BmpCMap,BmpDMap,BmpEMap,BmpFMap
};
const unsigned char SegCS[6] = {0xFE,0xFD,0xFB,0xF7,0xEF,0xDF};              //显示片选
unsigned char SegBuf[6] = {BmpPMap,Bmp1Map,BmpCMap,Bmp1Map,Bmp8Map,BmpFMap}; //显示缓冲

//-------------------------------------------------------------------------------
// 数码管显示驱动
//-------------------------------------------------------------------------------
void SegDisplay(void)
{
static unsigned char i = 0;
unsigned char j;
unsigned char tep;
tep = SegCS;         //片选输出
for(j=0;j<8;j++)        //8位
{
  if(tep&0x80) SDAT = 1;
  else         SDAT = 0;
  SCLK = 1;
  SCLK = 0;
  tep = tep<< 1;
}
tep = SegBuf;        //数据输出
for(j=0;j<8;j++)        //8位
{
  if(tep&0x80) SDAT = 1;
  else         SDAT = 0;
  SCLK = 1;
  SCLK = 0;
  tep = tep<< 1;
}

if(i < 5) i ++;        //扫描6位
else      i = 0;
}
//-------------------------------------------------------------------------------

//-------------------------------------------------------------------------------
// ADC采集程序
//-------------------------------------------------------------------------------
unsigned int  SampleADValue[8];    // 8次采样
unsigned int  AvgADValue = 0;      // AD采样平均值
unsigned char ADConverStep = 0;    // AD采样频步
void GET_ADValue(void)
{
unsigned char i;
unsigned int ConverValue;
do
{
}while(ADCON0bits.GO_DONE);   //等待转换完成
ConverValue = ADRESH;         //处理10位结果
ConverValue = (ConverValue << 8) + ADRESL;
SampleADValue[ADConverStep] = ConverValue;
if (ADConverStep == 7)  
{
  ConverValue = 0;
  for (i = 0; i < 8 ; i++)
  {
   ConverValue += SampleADValue;
  }
  AvgADValue = ConverValue >> 3;
  ADConverStep = 0;
}
else
{
  ADConverStep++;
}
}
//-------------------------------------------------------------------------------
// TMR1定时器初始化
//-------------------------------------------------------------------------------
void TMR1_Init(void)
{   
TMR1H = 0xF0;             //4mS 4MHz
TMR1L = 0x98;        
T1CONbits.RD16 = 1;       //16位定时方式
T1CONbits.TMR1CS = 0;     //内部FOSC/4
PIE1bits.TMR1IE = 1;      //T1中断 ON
}
//-------------------------------------------------------------------------------
// ADC初始化
//-------------------------------------------------------------------------------
void ADC_Init(void)               // ADC 初始化
{
ADCON0 = 0b00000001;          // ADC模块使能
ADCON1 = 0b00001110;          // AN0 ADC输入
ADCON2 = 0b10111111;          // 右对齐  FRC
}
//-------------------------------------------------------------------------------
// 高优先级中断向量
//-------------------------------------------------------------------------------
#pragma code InterruptVectorHigh = 0x08
void InterruptVectorHigh(void)
{
_asm
goto  Interrupt_High        //跳到中断程
_endasm
}
//-------------------------------------------------------------------------------
// 高优先级中断服务程序
//-------------------------------------------------------------------------------
#pragma interrupt Interrupt_High
void Interrupt_High(void)
{
if(PIR1bits.TMR1IF)          //T1中断
{
  PIR1bits.TMR1IF = 0;     //清除标志位
  TMR1H = 0xF0;            //4MS
  TMR1L = 0x98;
  SegDisplay();            //扫描显示
  TickClock = 1;          //置位
}
if(PIR1bits.RCIF)            // 接收中断
{
  PIR1bits.RCIF = 0;
  TXREG = RCREG;           // 将收到的数据发出
  if(RCSTAbits.OERR)       // 接收溢出错误处理
  {
   RCSTAbits.CREN = 0;
   RCSTAbits.CREN = 1;
  }
}
}
//-------------------------------------------------------------------------------
// 计算温度值
//-------------------------------------------------------------------------------
int GET_TempValue(unsigned int ADCValue)
{
ADCValue = (32*ADCValue)/10;     // y = (3300/1024)* x

if(ADCValue >500)   ADCValue = (ADCValue - 500);   //零上   500mV时 零度
else                ADCValue = (500 - ADCValue);   //零下

return ADCValue;
}
void initled()//初始化数码管
{
SegBuf[0] = Bmp0Map;               // "T"
SegBuf[1] = Bmp0Map;                  // "P"
SegBuf[2] = Bmp0Map;    //千位
SegBuf[3] = Bmp0Map;//百位
SegBuf[4] = Bmp0Map;
SegBuf[5] = Bmp0Map;
}
//-------------------------------------------------------------------------------
// 数码管分段显示函数
//-------------------------------------------------------------------------------
void LEDisplay(unsigned int ADValue)
{
SegBuf[0] = Bmp0Map;               // "T"
SegBuf[1] = Bmp0Map;                  // "P"
SegBuf[2] = SegCode[ADValue/1000];    //千位
SegBuf[3] = SegCode[ADValue%1000/100];//百位
SegBuf[4] = SegCode[ADValue%100/10]|Smg_dp;  //十位 有小数点
SegBuf[5] = SegCode[ADValue%10];      //个位
}
//-------------------------------------------------------------------------------
// 主程序部分
//-------------------------------------------------------------------------------
void main(void)
{
unsigned int SystemTick = 0; // 串口发数据定时
TRISB = 0b11111100;          //RB0 RB1 输出
TMR1_Init();                 //定时器1初始化  
ADC_Init();                  //ADC初始化

INTCONbits.PEIE = 1;         //外设中断允许
INTCONbits.GIE  = 1;         //总中断允许
T1CONbits.TMR1ON= 1;         //使能T1
  initled();


while(1)
{
  if(TickClock)            //采集AD值
  {
   TickClock = 0;
   ADCON0bits.GO_DONE = 1;
   SystemTick ++;
   GET_ADValue();  
  }
  if(SystemTick > 300)     //发送1次AD采样值
  {
   SystemTick = 0;
   AvgADValue = GET_TempValue(AvgADValue);  //获取温度值
   LEDisplay(AvgADValue);                   //显示温度值
  }
}
}
//-------------------------------------------------------------------------------



我想把数码管显示和定时器分离,搞74HC146清楚数码管到底怎么驱动的。或者哪位大神帮忙注释下,
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏 分享淘帖 顶 踩
回复

使用道具 举报

沙发
ID:111634 发表于 2016-7-3 11:15 | 只看该作者
本帖最后由 zl2168 于 2016-7-3 11:21 编辑

是74HC164,不是74HC146。164是串入并出一位寄存器。
先给你个74HC164串入并出控制16循环灯案例吧
区别是:你的案例是8位段码和6位位码(共14位),我的案例是16位数据,实际上是一样的。


Proteus仿真一下,确认有效。

实例42 74HC164串行输出控制8-16循环灯.rar (53.19 KB, 下载次数: 4)

以上摘自张志良编著《单片机实验实训100例》 ISBN 978-7-5124-1603-1,北航社出版

书中电路和程序设计有详细说明,程序语句条条有注解。




回复

使用道具 举报

板凳
ID:472325 发表于 2019-2-7 11:09 | 只看该作者
要先保证一种情况下亮,定时与温度只是错开不断刷新的事
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

手机版|小黑屋|51黑电子论坛 |51黑电子论坛6群 QQ 管理员QQ:125739409;技术交流QQ群281945664

Powered by 单片机教程网

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