controller控制器怎么写_I2C控制器编程_框架
來源:百問網(wǎng)_嵌入式Linux wiki_jz2440 新1期視頻維基教程 (視頻文字版)
作者:韋東山
本文字?jǐn)?shù):3776,閱讀時(shí)長:5分鐘
我們現(xiàn)在來講I2C控制器怎么寫,它是I2C程序中最核心的地方,我們要先構(gòu)造幾個(gè)結(jié)構(gòu)體,這幾個(gè)結(jié)構(gòu)體放在i2c_controller.h里面。
我們要發(fā)出I2c傳輸時(shí),要構(gòu)造出i2c_msg,把構(gòu)造出的i2c_msg扔給下面的i2c_controller.c,i2c_controller.c會(huì)選擇某一個(gè)i2c控制器,使用里面的master_xfer來傳輸數(shù)據(jù), 所以我們需要構(gòu)造出一個(gè)i2c_controller結(jié)構(gòu)體。
i2c_controller.h文件
文件的內(nèi)容如下所示:
#ifndef _I2C_CONTROLLER_H#define _I2C_CONTROLLER_Htypedef struct i2c_msg {unsigned int addr; /* 7bits */int flags; /* 0 - write, 1 - read */int len;int cnt_transferred;unsigned char *buf;}i2c_msg, *p_i2c_msg;typedef struct i2c_controller {int (*int)(void);int (*master_xfer)(i2c_msg msgs, int num);char *name;}i2c_controller, *p_i2c_controller;#endif /* _I2C_CONTROLLER_H */解析:我們構(gòu)造這兩個(gè)結(jié)構(gòu)體,我們要把它放在i2c_controller.c把它用起來,
i2c_controller.c文件
文件的內(nèi)容如下所示:
include "i2c_controller.h"#define I2C_CONTROLLER_NUM 10/* 有一個(gè)i2c_controller數(shù)組用來存放各種不同芯片的操作結(jié)構(gòu)體 */static p_i2c_controller p_i2c_controllers[I2C_CONTROLLER_NUM];static p_i2c_controller p_i2c_con_selected;void register_i2c_controller(p_i2c_controller *p){int i;for (i = 0; i < I2C_CONTROLLER_NUM; i++){if (!p_i2c_controllers[i]){p_i2c_controllers[i] = p;return;}}}解析:register_i2c_controller函數(shù)用于把參數(shù)中的結(jié)構(gòu)體指針,注冊(cè)到p_i2c_controllers指針數(shù)組中。
/* 根據(jù)名字來選擇某款I(lǐng)2C控制器 */int select_i2c_controller(char *name){int i;for (i = 0; i < I2C_CONTROLLER_NUM; i++){if (p_i2c_controllers[i] && !strcmp(name, p_i2c_controllers[i]->name)){p_i2c_con_selected = p_i2c_controllers[i];return 0;}}return -1;}解析:select_i2c_controller函數(shù)根據(jù)參數(shù)中的名字(name) 從p_i2c_controllers指針數(shù)組中取出對(duì)應(yīng)的結(jié)構(gòu)體指針復(fù)制給p_i2c_con_selected結(jié)構(gòu)體指針(靜態(tài)全局變量)。
/* 實(shí)現(xiàn) i2c_transfer 接口函數(shù) */int i2c_transfer(i2c_msg msgs, int num){return p_i2c_con_selected->master_xfer(msgs, num);}解析:i2c_transfer接口函數(shù),調(diào)用選擇的p_i2c_con_selected成員中master_xfer函數(shù)。
void i2c_init(void){/* 注冊(cè)下面的I2C控制器 */s3c2440_i2c_con_add();/* 選擇某款I(lǐng)2C控制器 *//* 調(diào)用它的init函數(shù) */}解析:s3c2440_i2c_con_add()函數(shù),把定義的s3c2440_i2c_con結(jié)構(gòu)體注冊(cè)到p_i2c_controllers數(shù)組中。
s3c2440_i2c_controller.c文件
中斷服務(wù)函數(shù),當(dāng)發(fā)成中斷時(shí),就會(huì)調(diào)用中斷服務(wù)函數(shù),代碼如下
void i2c_interrupt_func(int irq){/* 每傳輸完一個(gè)數(shù)據(jù)將產(chǎn)生一個(gè)中斷 *//* 對(duì)于每次傳輸, 第1個(gè)中斷是"已經(jīng)發(fā)出了設(shè)備地址" */}s3c2440_i2c_con_init函數(shù),用來初始化I2C,控制器代碼如下:
void s3c2440_i2c_con_init(void){/* 設(shè)置時(shí)鐘 *//* [7] : IIC-bus acknowledge enable bit, 1-enable in rx mode * [6] : 時(shí)鐘源, 0: IICCLK = fPCLK /16; 1: IICCLK = fPCLK /512 * [5] : 1-enable interrupt * [4] : 讀出為1時(shí)表示中斷發(fā)生了, 寫入0來清除并恢復(fù)I2C操作 * [3:0] : Tx clock = IICCLK/(IICCON[3:0]+1). * Tx Clock = 100khz = 50Mhz/16/(IICCON[3:0]+1) */IICCON = (0<<6) | (1<<5) | (30<<0);/* 注冊(cè)中斷處理函數(shù) */register_irq(27, i2c_interrupt_func);}解析:
1).IICCON = (0<<6) | (1<<5) | (30<<0); 設(shè)置IICCON控制寄存器。選擇發(fā)送時(shí)鐘,使能中斷。
2).register_irq(27, i2c_interrupt_func):注冊(cè)中斷處理函數(shù),當(dāng)發(fā)生I2C中斷的時(shí)候就會(huì)調(diào)用i2c_interrupt_func中斷處理函數(shù)。
初始化完成后,就可以調(diào)用do_master_tx寫I2C從機(jī)了,這個(gè)函數(shù)僅僅啟動(dòng)I2C傳輸,然后等待,直到數(shù)據(jù)在中斷服務(wù)程序中傳輸完畢后再返回。函數(shù)代碼如下:
void do_master_tx(p_i2c_msg msg){msg->cnt_transferred = 0;/* 設(shè)置寄存器啟動(dòng)傳輸 *//* 1. 配置為 master tx mode *//* 2. 把從設(shè)備地址寫入IICDS */IICDS = msg->addr<<1;/* 3. IICSTAT = 0xf0 , 數(shù)據(jù)即被發(fā)送出去, 將導(dǎo)致中斷產(chǎn)生 */IICSTAT = 0xf0;/* 后續(xù)的傳輸由中斷驅(qū)動(dòng) *//* 循環(huán)等待中斷處理完畢 */while (msg->cnt_transferred != msg->len);}解析:
1).IICDS = msg->addr<<1: 把從機(jī)地址(高7位,所以需要向右移一位)寫入到IICDS寄存器中。
2).IICSTAT = 0xf0:設(shè)置IICSTAT寄存器,將s3c2440設(shè)為主機(jī)發(fā)送器,并發(fā)出S信號(hào)后,緊接著就發(fā)出從機(jī)地址。后續(xù)的傳輸工作將在中斷服務(wù)程序中完成。
do_master_rx函數(shù)的實(shí)現(xiàn)和do_master_tx函數(shù)類似,代碼如下:
void do_master_rx(p_i2c_msg msg){msg->cnt_transferred = 0;/* 設(shè)置寄存器啟動(dòng)傳輸 *//* 1. 配置為 Master Rx mode *//* 2. 把從設(shè)備地址寫入IICDS */IICDS = (msg->addr<<1)|(1<<0);/* 3. IICSTAT = 0xb0 , 從設(shè)備地址即被發(fā)送出去, 將導(dǎo)致中斷產(chǎn)生 */IICSTAT = 0xb0;/* 后續(xù)的傳輸由中斷驅(qū)動(dòng) *//* 循環(huán)等待中斷處理完畢 */while (msg->cnt_transferred != msg->len);}解析: 1).IICDS = (msg->addr<<1)|(1<<0):把從設(shè)備地址寫入IICDS,前7位是從機(jī)地址,第8位表示傳輸方向(0表示寫操作,1表示讀操作)。
s3c2440傳輸函數(shù),根據(jù)標(biāo)志位flags,來指明是讀/寫(1:讀 0:寫)。代碼如下:
int s3c2440_master_xfer(p_i2c_msg msgs, int num){int i;for (i = 0; i < num; i++){if (msgs[i]->flags == 0)/* write */do_master_tx(msgs[i]);elsedo_master_rx(msgs[i]);}}我們定義一個(gè)i2c_controller結(jié)構(gòu)體s3c2440_i2c_con。下面的代碼對(duì)他進(jìn)行初始化。
static i2c_controller s3c2440_i2c_con = {.name = "s3c2440",.init = s3c2440_i2c_con_init,.master_xfer = s3c2440_master_xfer,};s3c2440_i2c_con_add函數(shù)把上面定義的s3c2440_i2c_con結(jié)構(gòu)體注冊(cè)到上層的i2c_controller數(shù)組中。
void s3c2440_i2c_con_add(void){register_i2c_controller(&s3c2440_i2c_con);}「新品首發(fā)」STM32MP157開發(fā)板火爆預(yù)售!首批僅300套
總結(jié)
以上是生活随笔為你收集整理的controller控制器怎么写_I2C控制器编程_框架的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 成都大熊猫基地停车场收费
- 下一篇: 成都大熊猫基地停车最新收费标准