當(dāng)前位置: 首頁(yè) > 傳感測(cè)量產(chǎn)品 > 工業(yè)傳感器 > 其他傳感器 > 色度傳感器
發(fā)布日期:2022-04-18 點(diǎn)擊率:158
現(xiàn)場(chǎng)總線通信控制器 FBC0409
驅(qū)動(dòng)程序開發(fā)手冊(cè)
周侗
中國(guó)科學(xué)院沈陽(yáng)自動(dòng)化研究所
2007 年10 月
現(xiàn)場(chǎng)總線通信控制器FBC0409 驅(qū)動(dòng)程序開發(fā)手冊(cè)
中國(guó)科學(xué)院沈陽(yáng)自動(dòng)化研究所
1、概述
本文給出了現(xiàn)場(chǎng)總線通信控制器 FBC0409 驅(qū)動(dòng)程序開發(fā)的相關(guān)說(shuō)明及示例程序,包括
FBC0409 芯片初始化、發(fā)送和接收操作、定時(shí)器使用等內(nèi)容。
FBC0409 性能說(shuō)明、內(nèi)部寄存器定義參見FBC0409 數(shù)據(jù)手冊(cè)。
2、FBC0409 初始化
FBC0409 初始化過(guò)程需要對(duì)命令寄存器、中斷屏蔽寄存器、DMA 接收數(shù)據(jù)區(qū)地址寄存
器等進(jìn)行設(shè)置。
FBC0409 中命令寄存器1(FB_CMD1)中的ARME 位(位0)是地址識(shí)別設(shè)置位,寫0
表示關(guān)閉地址識(shí)別功能,寫1 則打開地址識(shí)別功能。需要說(shuō)明的是,F(xiàn)BC0409 只支持FF H1
協(xié)議的地址識(shí)別功能,在開發(fā)PROFIBUS PA 時(shí),必須關(guān)閉地址識(shí)別功能。
FBC0409 初始化過(guò)程中,需要通過(guò)命令寄存器0(FB_CMD0)中的TFCE(位2)來(lái)選擇
報(bào)文發(fā)送過(guò)程中是由用戶還是硬件進(jìn)行報(bào)文校驗(yàn)和的生成工作,報(bào)文校驗(yàn)和有2 個(gè)字節(jié)。如
TFCE=0,表示在發(fā)送數(shù)據(jù)時(shí)需要由用戶自己在報(bào)文尾部添加2 個(gè)字節(jié)的校驗(yàn)碼;TFCE=1
則表示硬件自動(dòng)在報(bào)文尾部添加2 個(gè)字節(jié)的校驗(yàn)碼。
FBC0409 在接收數(shù)據(jù)時(shí),會(huì)自動(dòng)進(jìn)行校驗(yàn)檢查,然后通過(guò)狀態(tài)寄存器0(STATUS0)中
的位2(FCSF_STAT)來(lái)顯示校驗(yàn)結(jié)果。不管報(bào)文校驗(yàn)結(jié)果對(duì)或錯(cuò),F(xiàn)BC0406 都會(huì)將報(bào)文上傳
給用戶,但用戶程序通過(guò)FCSF_STAT 會(huì)知道校驗(yàn)的結(jié)果。
正常情況下,用戶程序?qū)⒂?jì)算出來(lái)的報(bào)文長(zhǎng)度再減去 2 個(gè)即得到報(bào)文真正長(zhǎng)度。
用戶在測(cè)試硬件時(shí),可以采用內(nèi)回環(huán)方式進(jìn)行。
示例代碼:
#define FBC0409_RAM 0x111111
#define FBC0409_REG 0x222222
unsigned short TD_ADDRESS , RXADDRESS;
void fbc0409_init(void)
{
int i;
TXADDRESS=0x0000; //發(fā)送緩沖區(qū)首址變量
RXADDRESS=0x0200; //接受緩沖區(qū)首址變量
//內(nèi)環(huán)回測(cè)試
*(FB0409_REG+0x01) = 0x2d; //FB_CMD1。0010 1101/半雙工/preamble=2
*(FB0409_REG+0x02) = 0x16; //FB_ CMD2。0001 0110/DMA 收發(fā)
*(FB0409_REG+0x03) = 0x27; //FB_CMD2。0010 0111/CPU 時(shí)鐘/
*(FB0409_REG+0x26) = 0x00; //FB_CMD3。0000 0000/CLK_DIV=0
*(FB0409_REG+0x04) = 0xff; //寫中斷狀態(tài)寄存器,用于清除所有中斷
*(FB0409_REG+0x05) = 0xff;
*(FB0409_REG+0x06) = 0xff;
*(FB0409_REG+0x07) = 0xff;
*(FB0409_REG+0x08) = 0x26; // ISR0_MSK。幀前定界碼/接收空閑/發(fā)送空閑
*(FB0409_REG+0x09) = 0x00; // ISR1_MSK。關(guān)閉地址識(shí)別中斷
*(FB0409_REG+0x0A) = 0x02; // ISR2_MSK。打開1/32ms 比較中斷
*(FB0409_REG+0x0B) = 0x00; // ISR3_MSK。關(guān)閉錯(cuò)誤中斷
*(FB0409_REG+0x12) = RXADDRESS>>8; //接收緩沖區(qū)首址,RCV_BUFPTR_HI
*(FB0409_REG+0x13) = RXADDRESS&0xFF; //接收緩沖區(qū)首址,RCV_BUFFPTR_LO
fbc0409_set32TimerCmp(32000); //此函數(shù)在定時(shí)器設(shè)置一節(jié)中給出
}
3、FBC0409 數(shù)據(jù)發(fā)送操作
FBC0409 支持兩種向現(xiàn)場(chǎng)總線發(fā)送數(shù)據(jù)的方式,即CPU 方式和DMA 方式。CPU 方式
是報(bào)文逐個(gè)字節(jié)發(fā)送,DMA 方式是成組數(shù)據(jù)發(fā)送,后者的效率要比前者高,在此推薦DMA
方式發(fā)送數(shù)據(jù)。
用戶程序在發(fā)送數(shù)據(jù)時(shí),需要考慮以何種方式生成 2 個(gè)字節(jié)的校驗(yàn)和。
下面僅給出了以 DMA 方式發(fā)送數(shù)據(jù)的示例。
示例代碼:
void fbc0409_send(unsigned char *paucData, unsigned char ucLength)
{
int i;
*(FB0409_REG+0x0E) = TXADDRESS>>8; //發(fā)送緩沖區(qū)首址,TRM_BUFFPTR_HI
*(FB0409_REG+0x0F) = TXADDRESS&0xFF; //發(fā)送緩沖區(qū)首址,TRM_BUFFPTR_LO
*(FB0409_REG+0x0C) = ucLength>>8; //發(fā)送數(shù)據(jù)字節(jié)數(shù),TRM_DATACNT_HI
現(xiàn)場(chǎng)總線通信控制器FBC0409 驅(qū)動(dòng)程序開發(fā)手冊(cè)
中國(guó)科學(xué)院沈陽(yáng)自動(dòng)化研究所
*(FB0409_REG+0x0D) = ucLength&0xff; //發(fā)送數(shù)據(jù)字節(jié)數(shù),TRM_DATACNT_LO
//復(fù)制數(shù)據(jù)到發(fā)送緩沖區(qū)中
memcpy(FB0409_RAM+TXADDRESS, paucData, ucLength);
*(FB0409_REG+0x00) = 0xdd; //向發(fā)送寄存器(TRM_REG)寄存器寫入任意值,啟動(dòng)發(fā)送
}
4、FBC0409 數(shù)據(jù)接收操作
FBC0409 使用一個(gè)中斷向量,通過(guò)判斷中斷主寄存器和中斷狀態(tài)寄存器0~3 中的狀態(tài)
位來(lái)確認(rèn)已經(jīng)發(fā)生的中斷事件。為了防止在中斷處理過(guò)程中又有新的中斷產(chǎn)生,在中斷處理
完成后需要再一次判斷是否有新的中斷發(fā)生。
FBC0409 接收數(shù)據(jù)的過(guò)程中,DMA 接收數(shù)據(jù)地址指針是變化的,每收到一個(gè)字節(jié),其
值就加1,永遠(yuǎn)指向存放下一個(gè)字節(jié)的空間。用戶程序在判斷接收到幀頭時(shí),需要記錄下
DMA 接收數(shù)據(jù)地址指針的當(dāng)前值uiframeHead,在判斷接收到幀尾時(shí),需要記錄下DMA
接收數(shù)據(jù)地址指針的當(dāng)前值uiframeEnd,然后用uiframeEnd 減去uiframeHead,然后再減
去2 就得到報(bào)文的長(zhǎng)度,這是因?yàn)檎G闆r下FBC0409 接收到的數(shù)據(jù)中包括2 個(gè)字節(jié)的校
驗(yàn)碼。
用戶程序判斷幀尾的方式有兩種,即接收空閑中斷和幀后定界碼中斷,可以通過(guò)設(shè)置中
斷狀態(tài)寄存器0(ISR0)來(lái)確定。這里我們推薦采用接收空閑中斷方式來(lái)判斷幀尾。
用戶程序在接收數(shù)據(jù)時(shí),可以根據(jù)狀態(tài)寄存器 0(STATUS0)中的位2(FCSF_STAT)來(lái)
了解報(bào)文的校驗(yàn)結(jié)果
這里給出了 DMA 方式接收數(shù)據(jù)的示例。
示例代碼:
unsigned short uiframeHead, uiframeEnd;
unsigned short uiRcvLen;
unsigned short aucRcvBuffer[256];
void fbc0409_int(void)
{
unsigned char ucISR_master, ucTemp;
ucISR_master = *(FB0409_REG+0x03); //保存中斷主寄存器值,操作過(guò)程中寄存器內(nèi)容被修改
do
{
if(ucISR_master) // ucISR_master 值不為0 表示有中斷事件發(fā)生
{
現(xiàn)場(chǎng)總線通信控制器FBC0409 驅(qū)動(dòng)程序開發(fā)手冊(cè)
中國(guó)科學(xué)院沈陽(yáng)自動(dòng)化研究所
if(ucISR_master & 0x04) //定時(shí)器中斷
{
ucTemp = *(FB0409_REG+0x06); //讀出并回寫中斷狀態(tài)寄存器2 來(lái)清定時(shí)
//器中斷
*(FB0409_REG+0x06) = ucTemp;
if (ucTemp & 0x02) // 1/32 ms 比較計(jì)數(shù)器中斷
{
}
}
if(ucISR_master & 0x01 == 0x01) //通信中斷
{
ucTemp = *(FB0409_REG+0x04); //讀出并回寫中斷狀態(tài)寄存器1 來(lái)清通信
//中斷
*(FB0409_REG+ 0x04) = ucTemp;
if(ucTemp & 0x20) //幀前定界碼中斷,表示接收到幀頭
{
uiframeHead = (*(FB0409_REG+0x12))*256+*(FB0409_REG+0x13);
uiRcvLen = 0;
}
if(ucTemp & 0x04) //接收空閑中斷,表示接收到幀尾
{
uiframeEnd = (*(FB0409_REG+0x12))*256+*(FB0409_REG+0x13);
uiRcvLen = (uiframeEnd - uiframeHead -2); //計(jì)算報(bào)文長(zhǎng)度
//示例中設(shè)定最大報(bào)文長(zhǎng)度為256。
if(uiRcvLen <= 256)
{
memcpy(aucRcvBuffer, FB0409_RAM+uiframeHead, uiRcvLen);
}
//重新設(shè)定接收緩沖區(qū)首址
*(FB0409_REG+0x12) = RXADDRESS>>8;
*(FB0409_REG+0x13) = RXADDRESS&0xFF;
}
if(ucTemp & 0x02) //發(fā)送空閑中斷
{
}
}
現(xiàn)場(chǎng)總線通信控制器FBC0409 驅(qū)動(dòng)程序開發(fā)手冊(cè)
中國(guó)科學(xué)院沈陽(yáng)自動(dòng)化研究所
}
ucISR_master = *(FB0409_REG+0x03);
}while(ucISR_master);
}
5、FBC0409 定時(shí)器應(yīng)用
FBC0409 提供了三個(gè)定時(shí)器:1ms、1/32ms 和octet,可以充分滿足用戶的需求。每種
定時(shí)器都有溢出操作和比較操作,當(dāng)每種定時(shí)器計(jì)數(shù)值達(dá)到0xFFFF 時(shí),即產(chǎn)生溢出中斷;
當(dāng)定時(shí)器計(jì)數(shù)值達(dá)到相應(yīng)比較寄存器的值時(shí),即產(chǎn)生比較中斷,具體是否產(chǎn)生中斷需要看相
應(yīng)中斷屏蔽器是的設(shè)置。
需要說(shuō)明的是,1/32ms 定時(shí)器是每個(gè)計(jì)數(shù)的單位是1/32ms ;1ms 定時(shí)器中每個(gè)計(jì)數(shù)
的單位是1ms;octet 定時(shí)器中每個(gè)計(jì)數(shù)的單位是8*1/32ms,即1/4ms。
FBC0409 只要一上電,其各個(gè)計(jì)數(shù)寄存器即開始工作,其計(jì)數(shù)值時(shí)刻在變化。
用戶程序定時(shí)時(shí),需要先讀出相應(yīng)計(jì)數(shù)值寄存器的當(dāng)前值 StartTime,加上定時(shí)長(zhǎng)度
Interval,得到EndTime,將EndTime 寫入相應(yīng)的比較寄存器中,當(dāng)計(jì)數(shù)值寄存器的值達(dá)到
EndTime 時(shí),即產(chǎn)生相應(yīng)的定時(shí)溢出中斷。參見中斷狀態(tài)寄存器2(ISR2)說(shuō)明。
用戶程序在讀取計(jì)數(shù)值時(shí),需要先鎖存計(jì)數(shù)器,向TIMER_LATCH(0x1F)寄存器中寫入
任意值即可實(shí)現(xiàn)內(nèi)部定時(shí)器鎖存操作,然后再讀計(jì)數(shù)器值。
示例代碼:
void fbc0409_set32TimerCmp(unsigned short uInterval)
{
unsigned short uStartTime = 0,uEndTime = 0;
unsigned char ucReg = 0;
//向TIMER_LATCH 寄存器中寫入任意值,以鎖存計(jì)數(shù)器
*(FB0409_REG+0x1F) = 0x01;
//讀1/32ms 計(jì)數(shù)器中當(dāng)前計(jì)數(shù)值
uStartTime = *(FB0409_REG+0x20)*256 +*(FB0409_REG+0x21);
//用當(dāng)前計(jì)數(shù)值加上定時(shí)長(zhǎng)度即得計(jì)數(shù)器結(jié)束時(shí)的值
uEndTime = uStartTime + uInterval;
//將計(jì)數(shù)器結(jié)束時(shí)的值寫入1/32ms 比較計(jì)數(shù)器中,
*(FB0409_REG+0x20) = (uEndTime >> 8) & 0xff; //高字節(jié)
*(FB0409_REG+0x21) = uEndTime & 0xff; //低字節(jié)
現(xiàn)場(chǎng)總線通信控制器FBC0409 驅(qū)動(dòng)程序開發(fā)手冊(cè)
中國(guó)科學(xué)院沈陽(yáng)自
下一篇: PLC、DCS、FCS三大控
上一篇: 索爾維全系列Solef?PV