這段時間在做一個使用飛思卡爾和CH376芯片使用串口通信的方式進行U盤讀寫的小項目,參考官方的UART_HW.C文件自己寫了一個給飛思卡爾用的硬件抽象層文件,但是期間遇到一個問題一直沒有解決。在沁恒技術(shù)支持人員的幫助下解決了這個問題。
整理了一下自己寫的這個文件,發(fā)出來,希望能對有類似需要的人有所幫助。之前在論壇也發(fā)過一個帖子http://m.findthetime.net/bbs/thread-63984-1.html問過這個問題,也感謝當(dāng)時查看這個帖子的朋友?,F(xiàn)在另發(fā)一帖是方便搜索引擎索引(第一次寫這個帖子的時候,寫完之后讓我登錄,沒發(fā)出去,只好登錄之后再寫一遍,T_T)
下面的藍(lán)色字體的部分是程序代碼:
再次感謝沁恒的幫助!
小白一枚,代碼寫得爛的地方不要吐槽我……
/* CH376芯片 按照標(biāo)準(zhǔn)異步串口連接的硬件抽象層 */
/* 在CH376芯片應(yīng)用過程中得到了沁恒官方的幫助,分享此文件是希望能夠?qū)ζ渌胍褂蔑w思卡爾與CH376以串口通信的方式協(xié)作的人有所幫助 */
/* 本文件是為MC9S12XS128單片機編寫的,應(yīng)當(dāng)可以(視型號差異可能需要略作修改)用于同系列的其他單片機 */
/* 應(yīng)用過程中需要的頂層函數(shù)可以到沁恒的官網(wǎng)下載,實際需要修改的只有底層硬件操作的內(nèi)容(也就是這個文件),參考了沁恒官方的UART_HW.C */
/* 小白一枚,所以可能這個問題實際不困難只是自身水平不夠所以遇到了麻煩,程序中如有不規(guī)范、效率低的寫法還請見諒 */
/* 該文件由吉林大學(xué)肯賽節(jié)能車隊一枚小組員編寫。如需使用請保留以上的文件說明信息。再次感謝沁恒的幫助! */
/*封裝I/O接口子程序 */
/*本文件使用MC9S12XS128-80QFP的SCI0模塊,要求使用40MHz的總線頻率
本文件所要求的硬件連接方式如下:
飛思卡爾引腳CH376的引腳
PS0( 63# )TXD
PS1( 64# )RXD
*/
/*為與CH376生產(chǎn)商所提供的文件系統(tǒng)函數(shù)庫兼容,仍使用與原始硬件抽象層文件相同的函數(shù)名稱和宏定義 */
#include "CH376INC.H"
/*附加的USB操作狀態(tài)定義 */
#defineERR_USB_UNKNOWN0xFA
#definexEndCH376Cmd( ) /* 結(jié)束CH376命令,僅用于SPI接口方式 */
#define UART_INIT_BAUDRATE 9600
//#define CH376_INT_WIREPTP_PTP0
/* CH376的INT腳會對外輸出中斷信號(低電平),但是不一定要與單片機的外部中斷引腳相連。如果不需要在中斷時觸發(fā)某種操作的話使用普通IO口,通過查詢IO口狀態(tài)得知CH376的中斷狀態(tài)也可以。在CH376_PORT_INIT函數(shù)中設(shè)置PORTA_PA0為輸入 */
void CH376_PORT_INIT( void )
{
/* 該函數(shù)實質(zhì)是設(shè)定SCI0模塊的波特率 */
//注意:需要確認(rèn)飛思卡爾沒有使用串口輸出監(jiān)控信息
SCI0BD=40000000 / 16 / UART_INIT_BAUDRATE;/* 設(shè)置40MHz總線下的波特率 */
SCI0CR1=0x00;
SCI0CR2=0x0C;/* 使能發(fā)送位和接收位 */
DDRP_DDRP0=0;
}
#ifdef UART_WORK_BAUDRATE
void SET_WORK_BAUDRATE( void )
{
/* 將單片機切換到正式通訊波特率 */
SCI0BD=40000000 / 16 / UART_WORK_BAUDRATE;/* 設(shè)置40MHz總線下的波特率 */
SCI0CR1=0x00;
SCI0CR2=0x0C;/* 使能發(fā)送位和接收位 */
}
#endif
void xWriteCH376Cmd( UINT8 mCmd )
{
UINT8 TempValue;
//while( SCI0SR1_TDRE == 0 );/* 等待數(shù)據(jù)發(fā)送緩沖區(qū)為空時開始發(fā)送 */
SCI0DRL=SER_SYNC_CODE1;
while( SCI0SR1_TDRE == 0 );/* 等待數(shù)據(jù)發(fā)送緩沖區(qū)為空,說明發(fā)送完成 */
SCI0DRL=SER_SYNC_CODE2;
while( SCI0SR1_TDRE == 0 );
/* 這里添加清除接收緩存區(qū)和接受標(biāo)志的操作 */
//通過讀取SCISR1寄存器,再讀取SCIDRL寄存器清零接收數(shù)據(jù)寄存器滿標(biāo)志位
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的中斷狀態(tài),低電平說明CH376發(fā)起了中斷請求 */
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 );/* 通訊接口不正常,可能原因有:接口連接異常,其它設(shè)備影響( 片選不唯一 ),串口波特率,一直在復(fù)位,晶振不工作 */
}
#ifdefUART_WORK_BAUDRATE
xWriteCH376Cmd( CMD21_SET_BAUDRATE );
/* 設(shè)置串口通訊波特率,公式見【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 );/* 通訊波特率切換失敗,建議通過硬件復(fù)位CH376后重試 */
}
#endif
xWriteCH376Cmd( CMD11_SET_USB_MODE ); /* 設(shè)備USB工作模式 */
xWriteCH376Data( 0x06 );
Result= xReadCH376Data( );
if( Result == CMD_RET_SUCCESS)
{
return( USB_INT_SUCCESS );
} else
{
return( ERR_USB_UNKNOWN ); /* 設(shè)置模式錯誤 */
}
}