RTOS之四裸机IIC 与TMP006温度计

参考:https://durant35.github.io/2017/11/30/TACouses_ES2017_MCU_GPIO/

TMP006温度计有三线:SCL,sda (Pa6 Pa7)和一根中断线连接到(PA2,这里没有使用中断功能)。

对于GPIO口,有两种功能:

A)作为I/O功能(也就是常说的GPIO功能

B)也有很多的内置外设(片上外设),像 I2C,ISP,USART等,为了节省引出管脚,这些内置外设基本上是与 I/O 口共用管脚的,也就是alt funtion(也就是 I/O 管脚的复用功能

注:对于开发板的IIC1的SCL,SDA是借用 Pa6 Pa7的alt funtion(也就是 I/O 管脚的复用功能),所以要先port A 的时钟使能,然后才能配置 Pa6 Pa7,比如的alt funtion,enable digital I/O。

1.先初始化IIC1:

void i2cinit(void){

SYSCTL_RCGCI2C_R |= 0x0002; // 1a) 激活 I2C1本身的时钟

SYSCTL_RCGCGPIO_R |= 0x0001; // 1b) 对TIVAC 必须先使能对应时钟,之后才能使能 Port A的 各种配置

while((SYSCTL_PRGPIO_R&0x01) == 0){};// allow time for clock to stabilize

// 2) no need to unlock PA7-6

GPIO_PORTA_AMSEL_R &= ~0xC0; // 3) 禁用 PA7-6的模拟功能

GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0x00FFFFFF)+0x33000000;

GPIO_PORTA_ODR_R |= 0x80; // 5) enable open drain on PA7 only

GPIO_PORTA_AFSEL_R |= 0xC0; // 6) 使能 PA7-6的多路复用功能(就是配置 PA7-6 为 I2C1)

GPIO_PORTA_DEN_R |= 0xC0; // 7) 配置 PA7-6 e数字IO模式,而不是模拟IO

I2C1_MCR_R = I2C_MCR_MFE; // 8) master function enable

I2C1_MTPR_R = 39; // 9) configure for 100 kbps clock

// 20*(TPR+1)*12.5ns = 10us, with TPR=39

}

2. BSP_TempSensor_Init

// Initialize a GPIO pin for input, which corresponds

// pins J2.11 (Temperature Sensor interrupt). 这里我们没用到中断读温度,可以不配置PA2

// two I2C pins J1.9 (SCL) and J1.10 (SDA).

void BSP_TempSensor_Init(void){

i2cinit();

// 1) activate clock for Port A (done in i2cinit())

// allow time for clock to stabilize (done in i2cinit())

// 2) no need to unlock PA2

GPIO_PORTA_AMSEL_R &= ~0x04; // 3) disable analog on PA2

// GPIO_PORTA_AMSEL_R |= 0x04; // 4) configure PA2 as GPIO

GPIO_PORTA_PCTL_R = (GPIO_PORTA_PCTL_R&0xFFFFF0FF)+0x00000000;

GPIO_PORTA_DIR_R &= ~0x04; // 5) make PA2 input

GPIO_PORTA_AFSEL_R &= ~0x04; // 6) disable alt funct on PA2

GPIO_PORTA_DEN_R |= 0x04; // 7) enable digital I/O on PA2

}

3. BSP_TempSensor_Start

void static tempsensorstart(uint8_t slaveAddress){

I2C_Send3(slaveAddress, 0x02, 0x75, 0x00);

}

//解释值,转换成温度

void static tempsensorend(uint8_t slaveAddress, int32_t *sensorV, int32_t *localT){

int16_t raw;

I2C_Send1(slaveAddress, 0x00); // pointer register 0x00 = Sensor Voltage Register

raw = I2C_Recv2(slaveAddress);

*sensorV = raw*15625; // 156.25 nV per LSB

I2C_Send1(slaveAddress, 0x01); // pointer register 0x01 = Local Temperature Register

raw = I2C_Recv2(slaveAddress);

*localT = (raw>>2)*3125; // 0.03125 C per LSB

}

#define TEMPINT (*((volatile uint32_t *)0x40004010)) /* PA2 */

int TempBusy = 0; // 0 = idle; 1 = measuring

void BSP_TempSensor_Input(int32_t *sensorV, int32_t *localT){

int32_t volt, temp;

TempBusy = 1;

tempsensorstart(0x40);

while(TEMPINT == 0x04){}; // wait for conversion to complete

tempsensorend(0x40, &volt, &temp);

*sensorV = volt;

*localT = temp;

TempBusy = 0;

}

// ------------BSP_TempSensor_Start------------

// Assumes: BSP_TempSensor_Init() has been called

void BSP_TempSensor_Start(void){

if(TempBusy == 0){

// no measurement is in progress, so start one

TempBusy = 1;

tempsensorstart(0x40);

}

}

int BSP_TempSensor_End(int32_t *sensorV, int32_t *localT){

int32_t volt, temp;

if(TempBusy == 0){

// no measurement is in progress, so start one

TempBusy = 1;

tempsensorstart(0x40);

return 0; // measurement needs more time to complete

} else{

// measurement is in progress

if(TEMPINT == 0x04){

return 0; // measurement needs more time to complete

} else{

tempsensorend(0x40, &volt, &temp);

*sensorV = volt;

*localT = temp;

TempBusy = 0;

return 1; // measurement is complete; pointers valid

}

}

}

5 调用

void Task4(void){int32_t voltData,tempData;

int done;

BSP_TempSensor_Init();

while(1){

TExaS_Task4(); // records system time in array, toggles virtual logic analyzer

Profile_Toggle4(); // viewed by a real logic analyzer to know Task4 started

BSP_TempSensor_Start();

done = 0;

while(done == 0){

done = BSP_TempSensor_End(&voltData,&tempData); // waits about 1 sec

}

TemperatureData = tempData/10000;

}

}

你可能感兴趣的:(RTOS,RTOS,linux)