飞思卡尔MC9S12G64串口发送接收驱动

因为之前刚入职,对串口调试不了解,下面整理一下书上的串口程序。  移植性还比较强

使用说明:MC9S12系列的串口有两种查询方式

               1》使用中断方式查询

               2》在主函数中使用轮询的方式的方法进行查询

             这两种方法在下面函数中都有体现,需要在用的时候注意分别提取

             主要是初始化的SCI1CR2的寄存器配置和调用中断的时候,注意串口1的中断号是VectorNumber_Vsci1     21

                                                                                                            注意串口0的中断号是VectorNumber_Vsci0    20

 

            下面是放到主函数中采用轮询方式时调用的函数

 /*************************串口轮询方式检测*********************************************************************************/        
 #if 0    
       if(SCI1SR1_RDRF) 
       {
        JieSHOU_Ddate[i]=SCI1DRL;
        i++;
        if(i==12) 
        {
         i=0;
         JieSHOU_flag=1;    //接收够12 个数组数据
        }
       }
                                                                        
      //MFD_Printf("JieSHOU_Ddate  %d!!\r\n",JieSHOU_Ddate[i]);
 #endif 

*************************************************************************************************************************************************

下面是原版函数,具体使用可根据自己需求改动!

********

 

/*---- include ---------------------------------------*/
#include  Printf.h"
#include <mc9s12g64.h>  
#include <stdarg.h>
/*---- config-----------------------------------------*/
#if MFD_DBGUG
const char Hex[] = "0123456789ABCDEF";
unsigned int JieSHOU_Ddate[12];


char ASCALL_TO16[4];
int i=0;
char JieSHOU_flag;
unsigned int JieSHOU(); 
/*----------------------------------------------------*/
/*******************************************************
* 函数名:void USART_Init(void)
* 创建:ZXL
* 功能:串口初始化
* 版本:1.0.0
* 日期:2019年1月17日
*******************************************************/
void USART_Init(void)
{
/*********只发配置************************/
#if 0
    SCI1BD = 14;        //波特率115200
    SCI1CR1 = 0x00;        //模式配置 数据位:8 校验位:无 停止位:1
    SCI1CR2 = 0x08;        //发送接收配置
#endif

#if 1
/*********接收中断方式*******************/     
  SCI1BD = 14;        //波特率115200
    SCI1CR1 = 0x00;        //模式配置 数据位:8 校验位:无 停止位:1
    SCI1CR2 = 0x2c;        //发送接收配置,,接收使能、、接收器满中断使能
#endif                       // SCI1CR2_ILIE=1;线路空闲使能
/*********接收查询方式*******************/     

#if 0                 
    SCI1BD = 14;        //波特率115200
    SCI1CR1 = 0x00;        //模式配置 数据位:8 校验位:无 停止位:1
    SCI1CR2 = 0x0c;        //发送接收配置,,接收使能、、接收器满中断使能     
#endif                  
}

/*******************************************************
* 函数名:void USART_SendByte(uint16_t Data)
* 创建:ZXL
* 功能:串口发送函数
* 版本:1.0.0
* 日期:2019年1月2日
*******************************************************/
static void USART_SendByte(uint16_t Data)
{
    SCI1DRL = Data;
    while(!SCI1SR1_TC)
    {
        ;
    }
}

/*******************************************************
* 函数名:void DoPrint( const char *fmt, va_list ap ) //va_list  char
* 创建:ZXL
* 功能:执行打印函数
* 版本:1.0.0
* 日期:2019年1月2日
*******************************************************/
static void DoPrint( const char *fmt, va_list ap )
{
    char ch;
    char *ptr;
    int value;
    uint8_t fl_zero;
    uint32_t i, fl_len, cnt, mask = 1;
    

    while(1)
    {
    
        switch(ch = *fmt++)
        {
            case 0:
                return;
            case '%':
                if( *fmt != '%' )
                {
                    break;
                }
                else
                {
                }
                fmt++;
            default:
                USART_SendByte(ch);
                continue;
        }
        fl_zero = 0;
        cnt = 0;
        ch = *fmt++;
        if(ch == '0')
        {
            fl_zero = 1;
            ch = *fmt++;
            cnt = ch - '0';
            ch = *fmt++;
        }
        else if( (ch >= '0') && (ch <= '9'))
        {
            cnt = ch - '0';
            ch = *fmt++;
        }
        else
        {
        }
        fl_len = 4;
        switch(ch)
        {
            case 'l':
            case 'L':
                ch = *fmt++;
                fl_len = 4;
                break;
            case 'b':
            case 'B':
                ch = *fmt++;
                fl_len = 1;
                break;
            default:
                break;
        }
        switch(ch)
        {
            case 'd':
            case 'u':
                switch(fl_len)
                {
                    case 1:
                        if(ch == 'd')
                        {
                            value = (char)va_arg(ap, int);
                        }
                        else
                        {
                            value = (uint8_t)va_arg(ap, int);
                        }
                        break;
                    case 4:
                        if(ch == 'd')
                        {
                            value = (uint32_t)va_arg(ap, uint32_t);
                        }
                        else
                        {
                            value = (uint32_t)va_arg(ap, uint32_t);
                        }
                        break;
                    default:
                        break;
                } 
                if(value < 0)
                {
                    USART_SendByte('-');
                    value = value*(-1);
                }
                else
                {
                }
                if(cnt == 0)
                {
                    if(value == 0)
                    {
                        USART_SendByte('0');
                        continue;
                    }
                    else
                    {
                    }
                    for(cnt=0, mask=1; cnt<10; cnt++)
                    {
                        if((value / mask)==0)
                        {
                            break;
                        }
                        else
                        {
                        }
                        mask = mask * 10;
                    }
                } 
                else
                {
                }
                for(i = 0, mask = 1; i < cnt-1; i++)
                {
                    mask = mask*10;
                }
                while(1)
                {
                    ch = (value / mask) + '0';
                    if((ch=='0') && (fl_zero==0) && (mask != 1))
                    {
                        ch=' ';
                    }
                    else
                    {
                        fl_zero = 1;
                    }
                    USART_SendByte(ch);
                    value = value % (mask);
                    mask = mask / 10;
                    if(mask == 0)
                    {
                        break;
                    }
                    else
                    {
                    }
                } 
                continue;
            case 'x':
            case 'X':
                switch(fl_len)
                {
                    case 1:
                        value = (uint8_t)va_arg(ap, int);
                        break;
                    case 4:
                        value = (uint32_t)va_arg(ap, int);
                        break;
                    default:
                        break;
                }
                if(value <= 0x0F)
                {
                    cnt = 1;
                }
                else if(value <= 0xFF)
                {
                    cnt = 2;
                }
                else if(value <= 0xFFF)
                {
                    cnt = 3;
                }
                else if(value <= 0xFFFF)
                {
                    cnt = 4;
                }
                else if(value <= 0xFFFFF)
                {
                    cnt = 5;
                }
                else if(value <= 0xFFFFFF)
                {
                    cnt = 6;
                }
                else if(value <= 0xFFFFFFF)
                {
                    cnt = 7;
                }
                else
                {
                    cnt = 8;
                }
                for(i=0; i<cnt; i++)
                {
                    USART_SendByte(Hex[(value >> (cnt - i - 1) * 4) & 0x000F]);
                }
                continue;
            case 's':
                ptr = (char *)va_arg(ap, char*);
                while(*ptr!='\0')
                {
                    USART_SendByte(*ptr++);
                }
                continue;
            case 'c':
                value = va_arg(ap, int);
                USART_SendByte((uint8_t)value);
                continue;
            default:
                value = (uint16_t)va_arg(ap, int);
                continue;
        } 

    } 

/*******************************************************
* 函数名:void MFD_Printf(const char *fmt, ...)
* 创建:ZXL
* 功能:串口打印函数
* 版本:1.0.0
* 日期:2018年1月2日
*******************************************************/
void MFD_Printf(const char *fmt, ...)
{
    va_list ap;
    va_start(ap, fmt);
    DoPrint(fmt, ap);
    va_end(ap);
}


#else
void MFD_Printf(const char *fmt, ...)
{
}
#endif


unsigned int JieSHOU() 
{
  unsigned int Result;
  unsigned int Result_high;
   
  unsigned int Temp;    //清内存
  Temp=SCI1SR1;
  
  while(!SCI1SR1_RDRF);
  
  Result=SCI1DRL;
  Result_high=SCI1DRH;
 
  return Result;
  //return Result_high;
}
unsigned int num1111;

/******************SCI 中断方式查询************************************************/

#if 1
#pragma CODE_SEG NON_BANKED 
interrupt  VectorNumber_Vsci1 void Sci_Isr(void)   //串口1中断号   21
{
  
  SCI1CR2_RIE=0;       //中断申请禁止、RDRF  OR  接收数据寄存器满标志  溢出标志  
 
  
  JieSHOU_Ddate[i]=JieSHOU();
  
  MFD_Printf("JieSHOU_Ddate  %d!!\r\n",JieSHOU_Ddate[i]);
  i++;
  if(i==8) 
  {
    i=0;
    JieSHOU_flag=1;    //接收够12 个数组数据
  }
 
  SCI1CR2_RIE=1;      //中断申请允许、RDRF  OR  接收数据寄存器满标志  溢出标志 
  
}

#endif

 

***********************************************************************************************************************************************

以下为串口的.H文件

*******************************************************/
#ifndef __PRINTF_H
#define __PRINTF_H
/*-----debug open or colse-----------------------------*/
typedef signed char     int8_t; 
typedef signed short     int16_t; 
typedef signed int         int32_t; 
typedef unsigned char     uint8_t; 
typedef unsigned short     uint16_t; 
typedef unsigned int     uint32_t;

#define MFD_DBGUG           1
/*-----function----------------------------------------*/
extern void USART_Init(void);
extern void MFD_Printf(const char *fmt, ...);
extern unsigned int JieSHOU_Ddate[12];
extern unsigned int JieSHOU(); 
extern char JieSHOU_flag; 


extern int i; 
#endif

***********************************************************************************************************************************************

以下为串口的轮询方式

 /*************************串口轮询方式检测*********************************************************************************/        
 #if 0    
       if(SCI1SR1_RDRF) 
       {
        JieSHOU_Ddate[i]=SCI1DRL;
        i++;
        if(i==12) 
        {
         i=0;
         JieSHOU_flag=1;    //接收够12 个数组数据
        }
       }
                                                                        
      //MFD_Printf("JieSHOU_Ddate  %d!!\r\n",JieSHOU_Ddate[i]);
 #endif 

软件介绍: 平时我们最常用到的下载程序的方法是通过USB数据线或其他数据线进行程序的烧写,这个方式是通过外界提供给单片机高电压来对flash擦除和写入完成的。而Bootloader不需要外界提供高电压仅靠正常工作电压便可完成对flash的擦除和写入,从而达到更新程序的目的。Bootloader的最大优点是:在不需要外部编程器的情况下,对嵌入式产品的应用代码进行更新升级。它使得通过局域网或者Intemet远程更新程序成为可能。例如,如果有5000个基于MCU的电能表应用程序需要更新,电能表制造商的技术人员就可以避免从事对每一个电能表重新编程的巨大工作量,通过使用Bootloader的功能,由控制中心通过电能表抄表系统网络,远程对5 000个电表重新编程。可见,Bootloader功能对于嵌入式系统的广泛应用具有十分重要的意义。关于Flash的擦除和写入,真的是让我最费力的一部分,网上的相关资料很少,好不容易找到了一点相关代码,却发现程序不能正常的运行,而且更令人无解的是程序本身怎么检查都检查不出错误。好啦,一点一点的说说我的辛酸史。首先,如果你在寻找飞思卡尔的flash擦除写入操作,很遗憾的告诉你,如果你用的不是MC9S12XS系列,那么很有可能,你所需要的flash擦除写入操作和我接下来将要说明的擦除写入操作基本上不沾边(除了原理上),因为飞思卡尔不同系列的单片机对flash的擦除写入操作的定义差别很大,不注意型号的话反而会被误导。
MC9S12XEQ512MAL芯片是飞思卡尔公司推出的一款高性能微控制器,具有多个外设模块,其中包括CAN控制器。下面是关于MC9S12XEQ512MAL芯片CAN配置的详细介绍: MC9S12XEQ512MAL芯片的CAN控制器可以通过寄存器来配置。首先,需要设置CAN控制器的工作模式。可以选择单环回模式(Loopback Mode)、自发自收模式(Self-Reception Mode)、静默模式(Listen-Only Mode)以及正常模式(Normal Mode)。 在配置CAN控制器之前,还需要设置CAN的时钟源。MC9S12XEQ512MAL芯片的CAN控制器可以选择外部时钟源或者使用内部时钟源,根据需要进行相应的设置。 接下来,需要配置CAN的位率。MC9S12XEQ512MAL芯片的CAN控制器支持多种位率,根据需要选择合适的位率进行配置。 此外,还需要配置CAN控制器的过滤器。CAN控制器可以设置接收滤波器,用于过滤掉不需要接收的CAN帧,只接收特定的CAN帧。 在CAN控制器配置完成后,可以根据需求选择发送CAN帧或者接收CAN帧。对于发送CAN帧,需要设置CAN消息的标识符、数据长度以及数据内容。对于接收CAN帧,需要设置接收缓冲区,并且可以通过查询或中断方式来读取接收到的CAN帧。 最后,需要配置中断使能位以及相应的中断处理函数。MC9S12XEQ512MAL芯片的CAN控制器支持中断功能,可以在接收到CAN帧或者发送CAN帧完成时触发相应的中断。 以上就是关于MC9S12XEQ512MAL芯片CAN配置的简要介绍。通过对CAN控制器的设置,可以实现CAN通信功能,并根据具体需求进行配置和使用。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值