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

📄 sys_fun.c

📁 msp430F435做的医疗器械,包括语音模块,知识源于网络
💻 C
📖 第 1 页 / 共 3 页
字号:
/**************************************************************************
                            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 + -