|
#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清楚数码管到底怎么驱动的。或者哪位大神帮忙注释下,
|
|