这段时间在做一个使用飞思卡尔和CH376芯片使用串口通信的方式进行U盘读写的小项目,参考官方的UART_HW.C文件自己写了一个给飞思卡尔用的硬件抽象层文件,但是期间遇到一个问题一直没有解决。在沁恒技术支持人员的帮助下解决了这个问题。
整理了一下自己写的这个文件,发出来,希望能对有类似需要的人有所帮助。之前在论坛也发过一个帖子http://www.wch.cn/bbs/thread-63984-1.html问过这个问题,也感谢当时查看这个帖子的朋友。现在另发一帖是方便搜索引擎索引(第一次写这个帖子的时候,写完之后让我登录,没发出去,只好登录之后再写一遍,T_T)
下面的蓝色字体的部分是程序代码:
再次感谢沁恒的帮助!
小白一枚,代码写得烂的地方不要吐槽我……
/* CH376芯片 按照标准异步串口连接的硬件抽象层 */
/* 在CH376芯片应用过程中得到了沁恒官方的帮助,分享此文件是希望能够对其他想要使用飞思卡尔与CH376以串口通信的方式协作的人有所帮助 */
/* 本文件是为MC9S12XS128单片机编写的,应当可以(视型号差异可能需要略作修改)用于同系列的其他单片机 */
/* 应用过程中需要的顶层函数可以到沁恒的官网下载,实际需要修改的只有底层硬件操作的内容(也就是这个文件),参考了沁恒官方的UART_HW.C */
/* 小白一枚,所以可能这个问题实际不困难只是自身水平不够所以遇到了麻烦,程序中如有不规范、效率低的写法还请见谅 */
/* 该文件由吉林大学肯赛节能车队一枚小组员编写。如需使用请保留以上的文件说明信息。再次感谢沁恒的帮助! */
/*封装I/O接口子程序 */
/*本文件使用MC9S12XS128-80QFP的SCI0模块,要求使用40MHz的总线频率
本文件所要求的硬件连接方式如下:
飞思卡尔引脚CH376的引脚
PS0( 63# )TXD
PS1( 64# )RXD
*/
/*为与CH376生产商所提供的文件系统函数库兼容,仍使用与原始硬件抽象层文件相同的函数名称和宏定义 */
#include "CH376INC.H"
/*附加的USB操作状态定义 */
#defineERR_USB_UNKNOWN0xFA
#definexEndCH376Cmd( ) /* 结束CH376命令,仅用于SPI接口方式 */
#define UART_INIT_BAUDRATE 9600
//#define CH376_INT_WIREPTP_PTP0
/* CH376的INT脚会对外输出中断信号(低电平),但是不一定要与单片机的外部中断引脚相连。如果不需要在中断时触发某种操作的话使用普通IO口,通过查询IO口状态得知CH376的中断状态也可以。在CH376_PORT_INIT函数中设置PORTA_PA0为输入 */
void CH376_PORT_INIT( void )
{
/* 该函数实质是设定SCI0模块的波特率 */
//注意:需要确认飞思卡尔没有使用串口输出监控信息
SCI0BD=40000000 / 16 / UART_INIT_BAUDRATE;/* 设置40MHz总线下的波特率 */
SCI0CR1=0x00;
SCI0CR2=0x0C;/* 使能发送位和接收位 */
DDRP_DDRP0=0;
}
#ifdef UART_WORK_BAUDRATE
void SET_WORK_BAUDRATE( void )
{
/* 将单片机切换到正式通讯波特率 */
SCI0BD=40000000 / 16 / UART_WORK_BAUDRATE;/* 设置40MHz总线下的波特率 */
SCI0CR1=0x00;
SCI0CR2=0x0C;/* 使能发送位和接收位 */
}
#endif
void xWriteCH376Cmd( UINT8 mCmd )
{
UINT8 TempValue;
//while( SCI0SR1_TDRE == 0 );/* 等待数据发送缓冲区为空时开始发送 */
SCI0DRL=SER_SYNC_CODE1;
while( SCI0SR1_TDRE == 0 );/* 等待数据发送缓冲区为空,说明发送完成 */
SCI0DRL=SER_SYNC_CODE2;
while( SCI0SR1_TDRE == 0 );
/* 这里添加清除接收缓存区和接受标志的操作 */
//通过读取SCISR1寄存器,再读取SCIDRL寄存器清零接收数据寄存器满标志位
TempValue = SCI0SR1;
TempValue = SCI0DRL;
SCI0DRL=mCmd;
while( SCI0SR1_TDRE == 0 );
}
void xWriteCH376Data( UINT8 mData )
{
SCI0DRL=mData;
while( SCI0SR1_TDRE == 0 );
}
UINT8 xReadCH376Data( void )
{
UINT32 i;
for( i=0;i<50000;i++ )
{
if( SCI0SR1_RDRF == 1 )
{
return SCI0DRL;
}
}
return( 0 );
}
/*检测CH376的中断状态,低电平说明CH376发起了中断请求 */
UINT8 Query376Interrupt( void )
{
#ifdef CH376_INT_WIRE
return( CH376_INT_WIRE?FALSE:TRUE );
#else
if( SCI0SR1_RDRF )
{
return( TRUE );
} else
{
return( FALSE );
}
#endif
}
UINT8 mInitCH376Host( void )
{
UINT8 Result;
CH376_PORT_INIT( );/* 接口硬件初始化 */
xWriteCH376Cmd( CMD11_CHECK_EXIST );/* 测试单片机与CH376之间的通讯接口 */
xWriteCH376Data( 0x65 );
Result= xReadCH376Data( );
if( Result != 0x9A )
{
return( ERR_USB_UNKNOWN );/* 通讯接口不正常,可能原因有:接口连接异常,其它设备影响( 片选不唯一 ),串口波特率,一直在复位,晶振不工作 */
}
#ifdefUART_WORK_BAUDRATE
xWriteCH376Cmd( CMD21_SET_BAUDRATE );
/* 设置串口通讯波特率,公式见【CH376DS1.PDF】第7页 */
#ifUART_WORK_BAUDRATE >= (6000000/256)
xWriteCH376Data( 0x03 );
xWriteCH376Data( 256 - 6000000/UART_WORK_BAUDRATE );
#else
xWriteCH376Data( 0x02 );
xWriteCH376Data( 256 - 750000/UART_WORK_BAUDRATE );
#endif
SET_WORK_BAUDRATE( ); /* 将单片机切换到正式通讯波特率 */
Result= xReadCH376Data( );
if( Result != CMD_RET_SUCCESS)
{
return( ERR_USB_UNKNOWN );/* 通讯波特率切换失败,建议通过硬件复位CH376后重试 */
}
#endif
xWriteCH376Cmd( CMD11_SET_USB_MODE ); /* 设备USB工作模式 */
xWriteCH376Data( 0x06 );
Result= xReadCH376Data( );
if( Result == CMD_RET_SUCCESS)
{
return( USB_INT_SUCCESS );
} else
{
return( ERR_USB_UNKNOWN ); /* 设置模式错误 */
}
}