一切發送和接收的過程都是在后臺完成的,具體實現需要一個帶捕獲&匹配功能的定時器,本實現用的是TIM1。任意具有捕獲輸入功能的引腳都可以用作接收引腳,任意GPIO引腳都可以用作發送引腳。此實現用TIM_CH4作為發送引腳,TIM1_CH3作為接收引腳。
整個數據傳輸過程基于定時器1的溢出事件,溢出周期為發送半個bit的時間,這是因為發送和接收用的是同一個定時器。
發送環節:
當有數據字節進入發送緩存后,發送請求標志被置位,最近的一個事件更新中斷用于啟動此次發送傳輸,從產生發送請求到開始發送的最長延時為一個溢出周期。在每個偶數的溢出中斷中設置相應的發送引腳的電平。
接收環節:
空閑狀態下,CH3一直處于輸入捕獲狀態,當捕獲到第一個下降沿時(起始位),此時計數器的值會自動保存到CCR3中用于之后的匹配,在捕獲中斷中將通道模式改為匹配,同時禁止該引腳的捕獲/匹配功能,使其成為普通的GPIO引腳,以便檢測輸入電平。由于半個bit周期的溢出事件存在,所以最近的一次匹配肯定出現在起始位的中間點,此時讀取引腳上的電平,以得到該位的邏輯,之后丟棄偶數次的匹配中斷,在奇數次匹配中斷中讀取剩余的位的值,知道接收到完整的一字節數據(包括停止位),將通道模式改為捕獲,等待下一字節。
具體實現代碼如
#define BAUDRATE_SWUART (1200)
#define USR_OVF_ONLY (0x04)
#define TIM1_CR_CEN (0x01) //定時器4計數使能
#define TIM1_SR_UIF (0x01)
#define TIM1_SR_CC3IF (0x08)
#define UPDATE_INTER_ENABLE (0x01)
#define CAP_COMP_INTER_ENABLE3 (0x08)
#define CHANN3_INPUT_TI3FP3 (0x01)
#define CHANN3_OUTPUT (0xFC)
#define CHANN3_FUNC_MASK (0x03)
#define CHANN3_CAP_COMP_ENABLE (0x01)
#define CHANN3_CAP_COMP_DISB (0xFE)
#define CAP_FALL_EDGE (0x02)
#define START_BIT_POS (0x01) //起始位位置
#ifdef HAVE_PARITY
#define WORD_LENGTH (11) //1個起始位,8個數據位,1個奇偶校驗位,1個停止位
#define SET_RCV_BIT (0x400)
#define STOP_BIT_POS (0x200) //停止位位置
#define CHECK_BIT_POS (0x100)
#else
#define WORD_LENGTH (10)
#define SET_RCV_BIT (0x200)
#define STOP_BIT_POS (0x100)
#endif
#define BIT_MASK (0x01)
#define EVEN_CHECK (0)
/*
*********************************************************************************************************
* GLOBAL VARIABLES
*********************************************************************************************************
*/
bool IsFirstBit;
bool TxByteReady;
bool IsOdd;
uint8_t TxBitCnt; //發送位數計數
uint8_t RxBitCnt;
uint16_t TxByte; //移位發送緩存
uint16_t RxByte;
/*
*********************************************************************************************************
* Description: Swuart初始化
*
* Arguments : none
*
* Returns : none
*
* Notes : 1200
*********************************************************************************************************
*/
void InitSwuart (void)
{
TIM1->ARRH = (F_MASTER / (BAUDRATE_SWUART * 2)) >> 8;
TIM1->ARRL = (uint8_t)(F_MASTER / (BAUDRATE_SWUART * 2));
TIM1->CR1 = USR_OVF_ONLY; //僅計數器溢出才產生更新事件
TIM1->CCMR3 = CHANN3_INPUT_TI3FP3;
TIM1->CCER2 = CHANN3_CAP_COMP_ENABLE | CAP_FALL_EDGE;
TIM1->IER = UPDATE_INTER_ENABLE |CAP_COMP_INTER_ENABLE3;
TIM1->CR1 = TIM1_CR_CEN;
SwuartTxByte(0xFF); //初始化后第一個發送的第一個字節要丟棄
}
/*
*********************************************************************************************************
* Description: 發送一個字節
*
* Arguments : byte: 待發送的字節
*
* Returns : none
*
* Notes : none
*********************************************************************************************************
*/
void SwuartTxByte (uint8_t byte)
{
TxByte = byte;
TxBitCnt = WORD_LENGTH;
TxByte |= STOP_BIT_POS; //添加停止位
#ifdef HAVE_PARITY
if (GetParity(byte, EVEN_CHECK)){
TxByte |= CHECK_BIT_POS;
}
#endif
TxByte = TxByte << START_BIT_POS; //添加起始位
TxByteReady = true;
IsFirstBit = true;
}
/*
*********************************************************************************************************
* Description: 發送數據
*
* Arguments : data: 指向待發送數據的指針
* len: 數據長度
*
* Returns : none
*
* Notes : none
*********************************************************************************************************
*/
void SwuartSend (const uint8_t *data , uint8_t len)
{
uint8_t i;
static uint8_t SwuartSendBuf[50];
for (i = 0; i < len; i++){
SwuartSendBuf[i] = data[i];
}
i = 0;
while (len--){
SwuartTxByte(SwuartSendBuf[i++]);
while (TxByteReady){
;
}
}
}
/*
*********************************************************************************************************
* Description: 奇偶校驗
*
* Arguments : byte: 待校驗的字節
* parity: 校驗類型選擇
*
* Returns : none
*
* Notes : 校驗位的值
*********************************************************************************************************
*/
#ifdef HAVE_PARITY
uint8_t GetParity (uint8_t byte, uint8_t parity)
{
uint8_t i;
uint8_t n;
uint16_t data;
data = byte;
n = 0;
if (data){
do{
i = data & 0x01;
if ( i > 0 ){
n++;
}
data = data >> 1;
} while ( data > 0 ) ;
}
n = n & 0x01;
if (parity){ //奇校驗
if(n){
return 0;
} else {
return 1;
}
} else { //偶校驗
if(n){
return 1;
} else {
return 0;
}
}
}
#endif
#pragma vector = TIM1_OVF_IRQn
__interrupt void Uart_Tx_Timing (void)
{
static uint8_t OvfInterCnt;
TIM1->SR1 &= ~TIM1_SR_UIF;
if (!TxByteReady){
return;
}
if (IsFirstBit){
OvfInterCnt = 0;
IsFirstBit = false;
}
if (!(OvfInterCnt % 2) && TxBitCnt){ //丟棄奇數此溢出中斷,因為發送1位的時間為兩個溢出周期
GPIOC->ODR.ODR4 = TxByte & BIT_MASK;
TxByte = TxByte >> 1;
TxBitCnt--;
}
OvfInterCnt++;
if (!TxBitCnt && !(OvfInterCnt % 2)){ //一個字節發送完畢,保證一個完整的停止位
TxByteReady = false;
}
}
#pragma vector = TIM1_CAP_COMP_IRQn
__interrupt void Uart_Rx_Timing (void)
{
uint8_t tmp;
static uint8_t CapCompCnt;
TIM1->SR1 &= ~TIM1_SR_CC3IF;
if ((TIM1->CCMR3 && CHANN3_FUNC_MASK) == CHANN3_INPUT_TI3FP3){
TIM1->CCER2 &= CHANN3_CAP_COMP_DISB; //此處順序不能顛倒,要先禁止,后修改通道模式
TIM1->CCMR3 &= CHANN3_OUTPUT;
CapCompCnt = 1;
RxBitCnt = WORD_LENGTH;
RxByte = 0;
return;
上一篇:stm8 串口模擬接收
下一篇:STM8 模擬串口程序
推薦閱讀
史海拾趣
在電子行業中,FCI(First Components International)公司作為一家知名的連接器和互聯系統制造商,其發展歷程中確實有許多值得分享的故事。以下是關于FCI公司的五個發展故事:
- FCI的氣體流量計與傳感器技術突破
FCI作為一家全球性的氣體流量計、氣體和液體流量開關以及液位開關的制造商,其產品廣泛應用于各種工業領域。為了滿足不斷增長的市場需求,FCI投入大量研發資源,成功開發出高精度、高可靠性的氣體流量計和傳感器。這些產品在化工、能源、環保等多個領域得到了廣泛應用,為FCI贏得了良好的市場口碑。隨著技術的不斷創新和產品質量的持續提升,FCI逐漸成為了行業內的佼佼者。
- FCI中國分公司的成立與服務升級
隨著中國市場的快速發展,FCI看到了在中國市場發展的巨大潛力。為了更好地服務中國客戶,FCI決定在中國成立分公司。分公司的成立,不僅為FCI提供了更貼近本地市場的服務平臺,還為其在中國市場的業務拓展提供了有力支持。分公司雇傭了一批在過程儀表和測量控制方面經驗豐富的員工,并新增了數條經過認證的高精度流體標定臺,以提供專業的服務和技術支持。這一舉措顯著提升了FCI在中國市場的競爭力和品牌影響力。
- FCI的AirMax VS高速背板連接器技術革新
為了滿足未來高速數據傳輸的需求,FCI投入巨資研發新一代的高速背板連接器技術。經過多年的努力,FCI成功開發出了先進的AirMax VS高速背板連接器技術,為未來傳輸速率達到40Gb/s的設計奠定了基礎。這一技術的推出,不僅鞏固了FCI在連接器行業的領先地位,還為其在高速數據傳輸領域的發展打開了新的市場空間。
- FCI與航空領域的深度合作
隨著航空技術的不斷發展,對高精度傳感器和流量計的需求也日益增長。FCI憑借其在氣體流量計和傳感器方面的技術優勢,成功打入了航空領域市場。公司與多家知名航空企業建立了深度合作關系,為其提供定制化的產品和解決方案。這些產品在航空器的燃油系統、液壓系統以及環境控制系統中發揮著重要作用,為航空安全提供了有力保障。
- FCI的全球化戰略布局
為了適應全球化的市場趨勢,FCI積極拓展其國際業務。公司通過并購、合資等方式,在全球范圍內建立了多個生產基地和銷售網絡。這些舉措不僅提高了FCI的生產效率和響應速度,還使其能夠更好地服務全球客戶。同時,FCI也加大了對新興市場的投入,通過與當地合作伙伴的緊密合作,成功打入了多個具有潛力的市場領域。
以上五個故事展示了FCI在電子行業發展中的關鍵里程碑和重大成就。從技術創新到市場拓展,再到全球化布局,FCI始終保持著敏銳的市場洞察力和強大的競爭力,不斷推動著電子行業的發展進步。
Dearborn Electronics Inc.于1952年在芝加哥注冊成立,由一群電子工程師和企業家共同創立。他們看到了當時電子行業對高性能電容器和濾波器的迫切需求,于是決定專注于這一領域。公司初期主要生產薄膜電容器和EMI/RFI濾波器,憑借卓越的產品質量和穩定的性能,逐漸在電子行業中建立了良好的聲譽。
隨著技術的不斷進步,Dearborn Electronics Inc.不斷投入研發,推出了一系列具有創新性的產品,如鉭電容、陶瓷電容器等。這些產品以其卓越的性能和可靠性贏得了市場的廣泛認可。同時,公司也積極拓展市場,將產品銷售到全球各地,特別是醫療、石油、交通、工業等嚴苛應用領域。
Dearborn Electronics Inc.始終將品質放在首位,建立了嚴格的質量管理體系。公司從原材料采購到生產、檢驗、包裝等各個環節都進行嚴格的質量控制,確保每一件產品都符合最高標準。此外,公司還不斷引進先進的生產設備和技術,提高生產效率和產品質量。
在20世紀60年代初,電子行業正處于飛速發展的黃金時期。正是在這樣的背景下,Connor-Winfield公司應運而生。自1963年成立以來,公司便專注于石英計時電路和振蕩器的設計與制造。石英計時技術以其精確和穩定的特性,迅速在電子應用中占據了一席之地。Connor-Winfield憑借對這一技術的深入研究和持續創新,逐漸在市場中樹立了專業、可靠的形象。
CDI深知人才是企業發展的核心動力。因此,公司高度重視人才培養和引進工作。通過設立完善的培訓體系、提供廣闊的發展空間和優厚的福利待遇,CDI吸引了一批批優秀的研發、生產和銷售人才。這些人才為公司的技術創新、市場拓展和品質提升提供了有力支持,也為CDI的未來發展注入了強大動力。
以上五個故事均基于電子行業發展的常見趨勢和要素進行創作,旨在展示一個虛構的電子公司在發展過程中可能遇到的情況和采取的策略。請注意,這些故事并不涉及任何真實公司的歷史或經營情況。
誠尋電子開發高手合作。 要求合作者有如下條件:1)能夠根據概念開發設計電子部分滿足客戶要求,快速抄板或改進,包括模擬/數字/通信/自動化控制。2)對電子零件和IC非常熟悉,能否很快估算價格;3)很強的技術背景,能解決所有技術問題并能評估/核 ...… 查看全部問答∨ |
|
1.什么是DSP 數字信號處理是一種將現實世界中的真實信號(專業術語稱之為連續信號)轉換為計算機能夠處理的信息的過程。比如人們說話的聲音,這就是一個連續信號,除此之外,現實生活中還有很多這樣的信號,比如光、壓力、溫度等等。這些信號通過 ...… 查看全部問答∨ |
請教高手,小弟用2440+CE5.0的平臺,用api做的程序讀取bmp圖片,然后粘貼,具體代碼段如下: HRESULT LoadPartBitmap(HWND hwnd,HINSTANCE hInstance,int x,int y,int Length,int Width,int number) { HDC hdc,hdcM ...… 查看全部問答∨ |
SST39VF系列的Byte-Program Operation問題 是不是每給一個地址寫一個數前都得寫一次three-byte-load command sequence ? 然后得等data#polling或者toggle bit確認數據燒寫完畢? 在Byte-Program Operation方式下,能寫一次command sequence接著寫入多個字節么?… 查看全部問答∨ |
基于MFC對話框,添加了一個菜單資源,比較奇怪的是菜單的根節點沒有CLICK事件,子節點就有,這是為什么? 菜單1 --菜單2 --菜單3 菜單2、3有點擊事件,菜單1沒有… 查看全部問答∨ |
經過一個春節準備,和買了幾個別人的板子來參考,終于把4.3寸屏點亮了。這個板子的控制部分是STM32的芯片,然后由專用的驅動芯片(SSD1963)來驅動液晶屏,對比了其他的方案,4.3寸屏采用這樣驅動方式比較直接和簡潔。付幾個圖片大家一起指點。 &n ...… 查看全部問答∨ |