📄 sys_fun.c
字号:
/**************************************************************************
discrible:系统底层驱动
author :Ye Yun Kai
date :05.04.15(yy.mm.dd)
**************************************************************************/
#include "msp430x42x.h"
#include "Sys_data.h"
#include "Sys_fun.h"
void Mcu_init(void) //MCU内部硬件设置
{
Sys_init(); //系统总体资源配置
Osc_init(); //晶振设置
BasicTimer_init(); //定时器设置-------------(有功耗问题)
TimerA_init(); //定时器A设置
IO_init(); //IO口初始化
Sci_init(); //串口初始化
SD_init(); //模数转换模块初始化-----(有功耗问题)
Lcd_init(); //液晶设置
}
/************************************************************
discrible:MCU系统字设置
date :05.04.20
************************************************************/
void Sys_init(void) //系统总体资源配置
{
WDTCTL = WDTPW + WDTHOLD; // Stop watchdog timer
}
/***********************************************************
discrible:晶振初始化
date :05.04.20
***********************************************************/
void Osc_init(void) //晶振设置
{
SCFQCTL = 31; //PLL模块设置(MCLK = 1.048576MHz)
SCFI0 = 0x00;
SCFI1 = 0x00; //用于校准频率用(与SCFI0的第0和1位)
FLL_CTL0 = 0x20; //负载电容为8PF,选择XT1为LF模式,Fdco与D+无关(DCO+为0)
FLL_CTL1 = 0x00; //P1.5做为第二功能输出的频率(32.768KHz)
}
/************************************************************
discrible:基本定时器初始化
date :05.04.20
************************************************************/
void BasicTimer_init(void) //定时器设置
{
BTCTL = 0x0F; //频率源为ACLK,中断频率32768/256(7.8125ms),液晶频率Fclk=Fack/64(512Hz)0x0F
}
/************************************************************
discrible:定时器A初始化
date :05.04.20
*************************************************************/
void TimerA_init(void) //定时器A设置(只用到定时部分,没用输入捕获和输出比较)
{
TACTL = 0x0122; //输入源:ACLK, 分频系数:1(32768频率,定时器A 2S溢出一次), continuous up 模式
}
/***************************************************************
discrible:系统IO口初始化
date :05.04.20
***************************************************************/
void IO_init(void) //IO口初始化
{
// P1DIR |= 0x02; //设P1.1为输出(红外输出控制口)=====================================//影响功耗
P2DIR |= 0x08; //设P2.3为输出,用于控制R1111N301B电源
P2SEL |= 0x30; //设P2.4,P2.5为功能口(通讯收发口,若不屏蔽静态功耗为40~50uA)======//影响功耗
// P2DIR |= 0x30; //通讯口先不设为通讯口,设为输出
// P2OUT &= ~0x30; //置低
P1DIR |= 0x07; //P1.0,P1.1,P1.2通讯控制口,先设为输出口
P1OUT |= 0x07; //置高
// P1OUT &= ~0x01; //先置低(以接收数据)
// P1DIR |= 0x04; //控制口设为输出口(暂时屏蔽,若开启,系统电流很大,16mA)
P1SEL = 0x00; //P1.3~P1.7设为按键中断
P1IE = 0xF8; //中断使能
P1IES = 0x00; //边沿选择:0--->1(上升沿)
/*
P2SEL &= ~0x01; //P2.0设为低压检测(即掉电)中断
P2IE |= 0x01; //中断使能
P2IES |= 0x01; //边沿选择:1--->0(下降沿)
*/
P2SEL &= ~0x02; //P2.1设为脉冲中断
P2IE |= 0x02; //中断使能
P2IES &= ~0x02; //边沿选择:0--->1(上降沿)
P2DIR |= 0x01; //置P2.0输出(设为输出并置低,为了使其有个0状态,不要悬浮导致电平不确定
P2OUT &= ~0x01; //置低
P2DIR |= 0x04; //置P2.2输出(设为输出并置低,为了使其有个0状态,不要悬浮导致电平不确定
P2OUT &= ~0x04; //置低
// P2DIR |= 0x02; //测试用
}
/*****************************************************************************************
discrible:USART通讯部分
date :2005-5-31
******************************************************************************************/
/**************************************************************
discrible:串口初始化
date :05.04.20
***************************************************************/
void Sci_init(void) //串口初始化
{
U0CTL |= 0x01; //置"SWRST"
/*************************************************/
U0CTL |= 0xD0; //"CHAR","EVEN","PEN=1"
U0TCTL = 0x10; //发送控制(选择时钟:必须ACLK)
U0RCTL = 0x00; //接收控制
U0BR1 = 0x00; //波特率设置(2400)
U0BR0 = 0x0D;
U0MCTL = 0x53;
ME1 |= UTXE0 + URXE0; //开启发送模块,接收模块
/*************************************************/
U0CTL &= 0xFE; //清"SWRST"(若不清0,就无法将收中断和发中断置1)
sci_receive(); //准备接收
}
/**************************************************************
discrible:USART准备接收处理程序
date :05.04.20
***************************************************************/
void sci_receive(void)
{
unsigned char temp;
RX485_CTRL_SET_RX; //485控制口(置为接收状态)
receive_length =0;
temp = U0TXBUF; //接收数据缓冲
IE1 |= URXIE0; //开启接收中断
IE1 &= ~UTXIE0; //关闭发送中断
IFG1 &= ~URXIFG0; //清接收标志位
IFG1 &= ~UTXIFG0; //清发送标志位
}
/**************************************************************
discrible:USART准备发送处理程序
date :05.04.20
***************************************************************/
void sci_send(void)
{
sending_ptr = comm_buf;//发送指针指向缓冲区头
IE1 |= UTXIE0; //开启发送中断
IE1 &= ~URXIE0; //关闭接收中断
IFG1 &= ~URXIFG0; //清接收标志位
IFG1 &= ~UTXIFG0; //清发送标志位
U0TXBUF = 0xFF; //送前导符
}
/******************************************************************************
discrible:延时程序
date :05.04.20
******************************************************************************/
void Delay(unsigned int Times) //延时 Times ms
{
unsigned char i;
unsigned int j;
i=0;j=0;
for(i=0;i<Times;i++)
{
for(j=0;j<1000;j++)
{
;
}
}
}
/**************************************************************
discrible:20ms里程处理
date :05.04.20
***************************************************************/
void Process_20ms(void)
{
if((Comm_symbol & fReceive) == fReceive) //若数据帧不正确,使receive_length清0,
{ //使下次通讯时,保证使receive_length为0
Count_SCI_receive++; //避免下次正确通讯时不能正确接收
if(Count_SCI_receive >25)
{
receive_length =0;
Comm_symbol &= ~fReceive;
}
}
if((Comm_symbol & fSendStart) == fSendStart) //接收完成,延时20ms处理准备发送工作
{
if(++Count_SCI_send >2)
{
Count_SCI_send =0;
Comm_symbol &= ~fSendStart; //清0
sci_send();
}
}
if((Comm_symbol & fSendComplete) == fSendComplete) //发送完成延时20ms处理准备接收工作
{
if(++Count_SCI_send>2)
{
Count_SCI_send =0;
Comm_symbol &= ~fSendComplete; //清0
sci_receive();
}
}
}
/****************************************************************
discrible:SD模块初始化
date :05.04.20
****************************************************************/
void SD_init(void)
{
SD16CTL = 0x0120;//SD模块控制寄存器(bit.3影响功耗:先关闭;LP置1:允许低功耗,时钟:ACLK,不分频)
SD16CCTL0 = 0x0008; //通道0控制寄存器(单词转换,中断使能)
SD16CCTL1 = 0x0008; //通道1控制寄存器
SD16CCTL2 = 0x0008; //通道2控制寄存器
SD16INCTL0 = 0x08; //通道0输入寄存器(增益2倍)
SD16INCTL1 = 0x08; //通道1输入寄存器
SD16INCTL2 = 0x08; //通道2输入寄存器
SD16PRE0 = 0x00; //通道0预加载寄存器
SD16PRE1 = 0x00; //通道1预加载寄存器
SD16PRE2 = 0x00; //通道2预加载寄存器
}
/*****************************************************************************************
discrible:液晶显示部分
date :2005-5-31
******************************************************************************************/
/****************************************************************
discrible:液晶初始化
date :05.04.20
****************************************************************/
void Lcd_init(void) //液晶设置
{
LCDCTL = 0x7D; //选择S0~S23为segment口\ 4 mux mode\ 开启
}
/*******************************************************************
discrible:液晶驱动(只负责送物理数据,即转换过的段码值)
date :05.04.20
*******************************************************************/
void Lcd_buffer_update(unsigned char *temp_buffer) //Lcd驱动
{
unsigned char *lcd_ptr;
unsigned char i;
lcd_ptr =(unsigned char *)0x0091; //转换成地址
for(i=0;i<11;i++)
{
*lcd_ptr = *temp_buffer;
lcd_ptr++;
temp_buffer++;
}
}
/*****************************************************************
discrible:全显
date :05.04.20
*****************************************************************/
void Lcd_all(void) //系统初始数据设置
{
unsigned char i;
for(i=0;i<11;i++) //全显
Data_buffer[i] = 0xFF;
Lcd_buffer_update(Data_buffer);
}
/***************************************************************
discrible:液晶清0
date :05.04.20
***************************************************************/
void Lcd_clr(void)
{
unsigned char i;
for(i=0;i<11;i++) //显示缓冲清0
Data_buffer[i] = 0x00;
Lcd_buffer_update(Data_buffer);
}
/**************************************************************
discrible:数据更新到Data_buffer(Data_buffer里放数据对应的真值表段码值)
date :05.04.20
**************************************************************/
void Up_Datebuffer(unsigned char *add,unsigned char num)
{
unsigned char i;
if(num == 4) //所送数据有4个字节(确切说应该是3个半字节)
{
for(i=0;i<3;i++) //液晶从右数起6个"8"显示
{
Data_buffer[6-(i*2)] = Num_Disp[*(add+i) & 0x0F];
Data_buffer[5-(i*2)] = Num_Disp[(*(add+i) & 0xF0)>>4];//0x10--->0x01(移成正确的数)
}
Data_buffer[0] = Num_Disp[*(add+3) & 0x0F]; //液晶最左一个"8"显示
}
else //所送数据小于4个字节
{
for(i=0;i<num;i++)
{
Data_buffer[6-(i*2)] = Num_Disp[*(add+i) & 0x0F];
Data_buffer[5-(i*2)] = Num_Disp[(*(add+i) & 0xF0)>>4];//0x10--->0x01(移成正确的数)
}
if(num==2)//显示温度数据项和地址项时,若最高位为0,则不显示
{
if(add==Address)//地址项
{
for(i=0;i<3;i++)//Data_buffer[3],Data_buffer[4],Data_buffer[5]为0则将其不显
{
if(Data_buffer[3+i]==0xFA)//为0
Data_buffer[3+i]=0x00; //将其不显
}
}
else//-----------入口项,出口项,温差项(最小为0.01度,所以只不显一个)
{
if(Data_buffer[3]==0xFA) //为0
Data_buffer[3]=0x00; //将其不显
}
}
}
}
/************************************************************
discrible:提示符更新到Data_buffer(主层数据提示)
date :05.04.20
************************************************************/
void Up_Promptbuffer(unsigned char num)
{
switch(num)
{
case 0x01:Data_buffer[8] = 0x02; //热标志 (当前热量)
Data_buffer[9] = 0x70; //"k","W","h"
// Data_buffer[5] |= 0x01; //小数点"."
// Data_buffer[6] |= 0x01; //左框符1
break;
case 0x02:Data_buffer[8] = 0x01; //冷标志 (当前冷量)
Data_buffer[9] = 0x70; //"k","W","h"
break;
case 0x03:Data_buffer[10] = 0x04; //"m3" (当前流量)
Data_buffer[4] |= 0x01; //小数点"."
Data_buffer[6] |= 0x01; //左框符1
Data_buffer[2] |= 0x01; //左框符2
break;
case 0x04:Data_buffer[8] = 0x10; //进水温度标志 (进水温度)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -