99久久全国免费观看_国产一区二区三区四区五区VM_久久www人成免费看片中文_国产高清在线a视频大全_深夜福利www_日韩一级成人av

liuxiaofei126
認(rèn)證:VIP會員
所在專題目錄 查看專題
從IIC實測波形入手搞懂IIC通信
實例講解(一)移位寄存器
單片機之USB 硬件和數(shù)據(jù)的四種傳輸方式
實例講解(二)SPI通訊顯示電子星球
實例講解(三)之USB模擬串口
實例分析之可編程數(shù)控電源
作者動態(tài) 更多
stm32知識點總結(jié)
2021-11-24 23:12
工程師單片機LED項目
2021-11-11 07:46
電容型負載對跟隨器的影響
2021-10-28 23:33
圖騰柱和互補推挽兩個“小冤家”
2021-10-22 23:15
學(xué)習(xí)單片機的捷徑
2021-10-17 23:07

實例講解(三)之USB模擬串口

這段時間學(xué)習(xí)STM32的USB通信,今天分享USB模擬串口,先上最小系統(tǒng)板和原理圖

我們先來了解一下USB模擬串口方面的知識,記得D+要上拉1.5K電阻

1.stm32的USB固件庫

移植時,重點要修改USB_CONFIG文件夾下的代碼,USB_CORE下的代碼一般不用修改。

1.USB_CORE下的文件介紹

2.USB_CONFIG下的文件介紹

3.中斷

再看USB如何初始化

USB的配置通過上面三個函數(shù)完成:
       Set_USBClock();            //配置USB時鐘,即從72M主頻得到48M的USB時鐘(1.5分頻)
       USB_Interrupts_Config(); //設(shè)置USB喚醒中斷和USB低優(yōu)先級數(shù)據(jù)處理中斷  
       USB_Init();                     //初始化USB,主要是調(diào)用Virtual_Com_Port_init函數(shù),開啟USB部分的電源等
 一、USB虛擬串口數(shù)據(jù)發(fā)送:
//發(fā)送一個字節(jié)數(shù)據(jù)到USB虛擬串口
void USB_USART_SendData(u8 data)
{
	uu_txfifo.buffer[uu_txfifo.writeptr]=data;
	uu_txfifo.writeptr++;
	if(uu_txfifo.writeptr==USB_USART_TXFIFO_SIZE)//超過buf大小了,歸零.
	{
		uu_txfifo.writeptr=0;
	} 
}
該函數(shù)實現(xiàn)發(fā)送1字節(jié)數(shù)據(jù)到虛擬串口中。
這里用到了一個uu_txfifo結(jié)構(gòu)體,該結(jié)構(gòu)體是一個USB虛擬串口發(fā)送數(shù)據(jù)FIFO結(jié)構(gòu)體,定義如下:
//定義一個USB USART FIFO結(jié)構(gòu)體
typedef struct  
{										    
	u8  buffer[USB_USART_TXFIFO_SIZE];	//buffer
	vu16 writeptr;						//寫指針
	vu16 readptr;						//讀指針
}_usb_usart_fifo; 
extern _usb_usart_fifo uu_txfifo;		//USB串口發(fā)送FIFO
該結(jié)構(gòu)體用于處理USB串口要發(fā)送的數(shù)據(jù),所以通過USB串口發(fā)送的數(shù)據(jù),都將先存到結(jié)構(gòu)體的buffer數(shù)組(FIFO緩存區(qū))里面,USB_USART_TXFIFO_SIZE定義了該數(shù)組的大小,通過writeptr和readptr來控制FIFO的寫入和讀出。該結(jié)構(gòu)體buffer數(shù)據(jù)的寫入,是通過USB_USART_SendData()函數(shù)實現(xiàn)的。buffer數(shù)據(jù)的讀出(然后發(fā)送到USB)則是通過端點1的回調(diào)函數(shù)EP1_IN_Callback()函數(shù)實現(xiàn)的。
該函數(shù)在usb_endp.c中。代碼如下:
void EP1_IN_Callback (void)
{
	u16 USB_Tx_ptr;
	u16 USB_Tx_length; 
	if(uu_txfifo.readptr==uu_txfifo.writeptr)		//無任何數(shù)據(jù)要發(fā)送,直接退出
	{
		return;
	}
	if(uu_txfifo.readptr<uu_txfifo.writeptr)		//沒有超過數(shù)組,讀指針<寫指針
	{
		USB_Tx_length=uu_txfifo.writeptr-uu_txfifo.readptr;//得到要發(fā)送的數(shù)據(jù)長度
	}else											//超過數(shù)組了 讀指針>寫指針
	{
		USB_Tx_length=USB_USART_TXFIFO_SIZE-uu_txfifo.readptr;//得到要發(fā)送的數(shù)據(jù)長度 
	} 
	if(USB_Tx_length>VIRTUAL_COM_PORT_DATA_SIZE)	//超過64字節(jié)?
	{
		USB_Tx_length=VIRTUAL_COM_PORT_DATA_SIZE;	//此次發(fā)送數(shù)據(jù)量
	}
	USB_Tx_ptr=uu_txfifo.readptr;					//發(fā)送起始地址		
	uu_txfifo.readptr+=USB_Tx_length;				//讀指針偏移  
	if(uu_txfifo.readptr>=USB_USART_TXFIFO_SIZE)	//讀指針歸零
	{
		uu_txfifo.readptr=0;
	} 
	UserToPMABufferCopy(&uu_txfifo.buffer[USB_Tx_ptr], ENDP1_TXADDR, USB_Tx_length);
	SetEPTxCount(ENDP1, USB_Tx_length);
	SetEPTxValid(ENDP1);   
}
這個函數(shù)由USB中斷處理相關(guān)函數(shù)調(diào)用,將通過USB發(fā)送給電腦的數(shù)據(jù)拷貝到端點1的發(fā)送區(qū),然后通過USB發(fā)送給電腦,從而實現(xiàn)串口數(shù)據(jù)的發(fā)送。
 因為每次傳輸數(shù)據(jù)長度不超過VIRTUAL_COM_PORT_DATA_SIZE,所以USB的發(fā)送數(shù)據(jù)長度:USB_Tx_length的最大值,只能是VIRTUAL_COM_PORT_DATA_SIZE。
 以上就是USB虛擬串口數(shù)據(jù)發(fā)送過程。
 二、我們看看USB虛擬串口數(shù)據(jù)接收:
USB虛擬串口的接收,通過端點3來實現(xiàn),端點3的回調(diào)函數(shù)為EP3_OUT_Callback(),該函數(shù)也在usb_endp.c中,代碼如下:
void EP3_OUT_Callback(void)
{
	u16 USB_Rx_Cnt; 
	USB_Rx_Cnt = USB_SIL_Read(EP3_OUT, USB_Rx_Buffer);	//得到USB接收到的數(shù)據(jù)及其長度  
	USB_To_USART_Send_Data(USB_Rx_Buffer, USB_Rx_Cnt);	//處理數(shù)據(jù)(其實就是保存數(shù)據(jù)) 
	SetEPRxValid(ENDP3);								//時能端點3的數(shù)據(jù)接收
}
 該函數(shù)也是由USB中斷處理相關(guān)函數(shù)調(diào)用,該函數(shù)通過調(diào)用USB_To_USART_Send_Data函數(shù),實現(xiàn)USB接收數(shù)據(jù)的保存,
該函數(shù)在hw_config.c中實現(xiàn),代碼如下:
//處理從USB虛擬串口接收到的數(shù)據(jù)
//databuffer:數(shù)據(jù)緩存區(qū)
//Nb_bytes:接收到的字節(jié)數(shù).
void USB_To_USART_Send_Data(u8* data_buffer, u8 Nb_bytes)
{ 
	u8 i;
	u8 res;
	for(i=0;i<Nb_bytes;i++)
	{  
		res=data_buffer[i]; 
		if((USB_USART_RX_STA&0x8000)==0)		//接收未完成
		{
			if(USB_USART_RX_STA&0x4000)			//接收到了0x0d
			{
				if(res!=0x0a)USB_USART_RX_STA=0;//接收錯誤,重新開始
				else USB_USART_RX_STA|=0x8000;	//接收完成了 
			}else //還沒收到0X0D
			{	
				if(res==0x0d)USB_USART_RX_STA|=0x4000;
				else
				{
					USB_USART_RX_BUF[USB_USART_RX_STA&0X3FFF]=res;
					USB_USART_RX_STA++;
					if(USB_USART_RX_STA>(USB_USART_REC_LEN-1))USB_USART_RX_STA=0;//接收數(shù)據(jù)錯誤,重新開始接收	
				}					
			}
		}   
	}  
} 

最后下載驗證

發(fā)送和接受一致

聲明:本內(nèi)容為作者獨立觀點,不代表電子星球立場。未經(jīng)允許不得轉(zhuǎn)載。授權(quán)事宜與稿件投訴,請聯(lián)系:editor@netbroad.com
覺得內(nèi)容不錯的朋友,別忘了一鍵三連哦!
贊 6
收藏 7
關(guān)注 211
成為作者 賺取收益
全部留言
0/200
  • dy-blNlwnWV 2021-02-25 21:44
    佩服樓主
    回復(fù)
  • keyhei66 2021-01-15 18:49
    可以
    回復(fù)
  • 星球居民-YBPLIKJ1 2021-01-14 19:52
    不錯不錯
    回復(fù)
  • lihui710884923 2021-01-07 10:44
    有資料嗎?
    回復(fù)
主站蜘蛛池模板: 久久97超碰色中文字幕蜜芽 | 精品国产日韩亚洲一区二区 | 国产真实一区二区三区 | 性欧美69式xxxx | 青青草久草在线视频 | 国产在线不卡精品网站 | 九歌在线观看 | 亚洲网一区二区三区 | 成人国产精品一区在线观看播放 | 精品久久久久久久久久中文字幕 | 午夜福利精品导航凹凸 | 国产精品自产拍在线观看55 | 亚洲第一区精品 | 国产骚熟 | 一级黄色裸体视频 | 综合久久国产 | 91成人精品一区在线播放69 | Av天堂亚洲好男人 | 无码少妇一区二区三区 | 国产精品扒开腿做爽爽爽A片唱戏 | 久久看精品 | 国产精品福利一区 | 亚洲精品亚洲人成人网 | 中文字幕在线观看欧美 | 免费在线观看av的网站 | 精品一区日韩成人 | 国产精品中文字幕在线观看 | 亚洲日韩一区精品射精 | 久久人人槡人妻人人玩夜色AV | 亚洲VS成人无码人在线观看堂 | 大陆熟女丰满XXXXX富婆 | 国产精品久久久久久久久久新婚 | 伊人久久无码大香线蕉综合 | 成熟人妻换╳╳╳╳ | 人妻丰满熟妇无码区免费 | 67194中文字幕在线观看日韩 | 国内精品免费一区二区2001 | 久久香蕉国产线看观看6 | 97香蕉久久超级碰碰高清版 | 日本精品中文字幕在线不卡 | 自拍欧美日韩一区二区三区 |