- 模擬I2C驅動BMP280氣壓感測器
- 模擬SPI
- CAN通訊
模擬I2C驅動BMP280氣壓感測器
模擬I2C沒什麼好說的,只需要三個GPIO功能即可:設定SDA引腳的輸入以及輸出方向,設定SCL和SDA引腳的輸出高低電平,讀取SDA引腳的輸入值,直接將要用到的SCL和SDA引腳初始化為GPIO即可:
使用了開發板上的PTB5和PTB4,這兩個引腳經過了一個電平轉換晶片,高電平為3.3V。

直接上程式碼:
#define FAKE_I2C_SCL_PTB5_HIGH Siul2_Dio_Ip_WritePin(FAKE_I2C_SCL_PORT , FAKE_I2C_SCL_PIN , 1);
#define FAKE_I2C_SCL_PTB5_LOW Siul2_Dio_Ip_WritePin(FAKE_I2C_SCL_PORT , FAKE_I2C_SCL_PIN , 0);
#define FAKE_I2C_SDA_PTB4_HIGH Siul2_Dio_Ip_WritePin(FAKE_I2C_SDA_PORT , FAKE_I2C_SDA_PIN , 1);
#define FAKE_I2C_SDA_PTB4_LOW Siul2_Dio_Ip_WritePin(FAKE_I2C_SDA_PORT , FAKE_I2C_SDA_PIN , 0);
#define FAKE_I2C_SDA_PTB4_IN Siul2_Port_Ip_SetPinDirection(PORTB_L_HALF , 4 , SIUL2_PORT_IN);
#define FAKE_I2C_SDA_PTB4_OUT Siul2_Port_Ip_SetPinDirection(PORTB_L_HALF , 4 , SIUL2_PORT_OUT);
#define I2C_SDA_PTB4_READ Siul2_Dio_Ip_ReadPin(FAKE_I2C_SDA_PORT , FAKE_I2C_SDA_PIN)
void Fake_I2C_Idle_PTB5_PTB4()
{
FAKE_I2C_SDA_PTB4_OUT;
FAKE_I2C_SDA_PTB4_HIGH;
FAKE_I2C_SCL_PTB5_HIGH;
Pit0_Delay_us(4);
}
void Fake_I2C_Start_PTB5_PTB4(void)
{
FAKE_I2C_SDA_PTB4_OUT;
FAKE_I2C_SDA_PTB4_HIGH;
FAKE_I2C_SCL_PTB5_HIGH;
Pit0_Delay_us(4);
FAKE_I2C_SDA_PTB4_LOW;
Pit0_Delay_us(4);
FAKE_I2C_SCL_PTB5_LOW;
Pit0_Delay_us(4);
}
void Fake_I2C_Stop_PTB5_PTB4(void)
{
FAKE_I2C_SDA_PTB4_OUT;
FAKE_I2C_SDA_PTB4_LOW;
FAKE_I2C_SCL_PTB5_HIGH;
Pit0_Delay_us(4);
FAKE_I2C_SDA_PTB4_HIGH;
}
uint8_t Fake_I2C_Wait_Ack_PTB5_PTB4(void)
{
uint8_t rvalue;
FAKE_I2C_SDA_PTB4_OUT;
FAKE_I2C_SDA_PTB4_HIGH;
Pit0_Delay_us(4);
FAKE_I2C_SCL_PTB5_HIGH;
Pit0_Delay_us(4);
FAKE_I2C_SDA_PTB4_IN;
if(I2C_SDA_PTB4_READ)
{
rvalue = 1;
}
else
{
rvalue = 0;
}
FAKE_I2C_SCL_PTB5_LOW;
Pit0_Delay_us(4);
return rvalue;
}
void Fake_I2C_Ack_PTB5_PTB4(void)
{
FAKE_I2C_SDA_PTB4_OUT;
FAKE_I2C_SDA_PTB4_LOW;
Pit0_Delay_us(4);
FAKE_I2C_SCL_PTB5_HIGH;
Pit0_Delay_us(4);
FAKE_I2C_SCL_PTB5_LOW;
Pit0_Delay_us(4);
FAKE_I2C_SDA_PTB4_HIGH;
}
void Fake_I2C_NAck_PTB5_PTB4(void)
{
FAKE_I2C_SDA_PTB4_OUT;
FAKE_I2C_SDA_PTB4_HIGH;
Pit0_Delay_us(4);
FAKE_I2C_SCL_PTB5_HIGH;
Pit0_Delay_us(4);
FAKE_I2C_SCL_PTB5_LOW;
Pit0_Delay_us(4);
}
void Fake_I2C_Send_Byte_PTB5_PTB4(uint8_t txd)
{
uint8_t i;
FAKE_I2C_SDA_PTB4_OUT;
FAKE_I2C_SCL_PTB5_LOW;
for(i = 0 ; i < 8 ; i++)
{
if((txd & 0x80) >> 7)
{
FAKE_I2C_SDA_PTB4_HIGH;
}
else
{
FAKE_I2C_SDA_PTB4_LOW;
}
txd <<= 1;
Pit0_Delay_us(20);
FAKE_I2C_SCL_PTB5_HIGH;
Pit0_Delay_us(20);
FAKE_I2C_SCL_PTB5_LOW;
Pit0_Delay_us(20);
}
Pit0_Delay_us(20);
}
uint16_t Fake_I2C_Read_Byte_PTB5_PTB4(uint8_t ack)
{
uint8_t i;
uint16_t dat = 0;
FAKE_I2C_SDA_PTB4_IN;
for(i = 0 ; i < 8 ; i++)
{
FAKE_I2C_SCL_PTB5_LOW;
Pit0_Delay_us(20);
FAKE_I2C_SCL_PTB5_HIGH;
dat <<= 1;
if(I2C_SDA_PTB4_READ)
dat++;
Pit0_Delay_us(20);
}
if (!ack)
{
Fake_I2C_NAck_PTB5_PTB4();
}
else
{
Fake_I2C_Ack_PTB5_PTB4();
}
return dat;
}
uint8_t Fake_I2C_Read_Addr_PTB5_PTB4(uint8_t dev_addr , uint8_t reg)
{
uint8_t res;
Fake_I2C_Start_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4((dev_addr << 1) | 0);
Fake_I2C_Wait_Ack_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4(reg);
Fake_I2C_Wait_Ack_PTB5_PTB4();
Fake_I2C_Start_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4((dev_addr << 1) | 1);
Fake_I2C_Wait_Ack_PTB5_PTB4();
res = Fake_I2C_Read_Byte_PTB5_PTB4(0);
Fake_I2C_Stop_PTB5_PTB4();
return res;
}
void Fake_I2C_Read_Datas_PTB5_PTB4(uint8_t dev_addr , uint8_t reg , uint8_t data_len , uint8_t data[])
{
while(data_len)
{
*data = Fake_I2C_Read_Addr_PTB5_PTB4(dev_addr , reg++);
data++;
data_len--;
}
}
void Fake_I2C_Write_Reg_Data_PTB5_PTB4(uint8_t dev_addr , uint8_t reg , uint8_t data)
{
Fake_I2C_Start_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4((dev_addr << 1) | 0);
Fake_I2C_Wait_Ack_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4(reg);
Fake_I2C_Wait_Ack_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4(data);
Fake_I2C_Wait_Ack_PTB5_PTB4();
Fake_I2C_Stop_PTB5_PTB4();
}
void Fake_I2C_Write_Reg_Datas_PTB5_PTB4(uint8_t dev_addr , uint8_t reg , uint8_t data_len , uint8_t data[])
{
int i;
Fake_I2C_Start_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4((dev_addr << 1) | 0);
Fake_I2C_Wait_Ack_PTB5_PTB4();
Fake_I2C_Send_Byte_PTB5_PTB4(reg);
Fake_I2C_Wait_Ack_PTB5_PTB4();
for(i = 0 ; i < data_len ; i++)
{
Fake_I2C_Send_Byte_PTB5_PTB4(data[i]);
Fake_I2C_Wait_Ack_PTB5_PTB4();
}
Fake_I2C_Stop_PTB5_PTB4();
Pit0_Delay_ms(10);
}
#define ATH20_SLAVE_ADDRESS 0x38
#define BMP280_PRESSURE_OSR (BMP280_OVERSAMP_8X)
#define BMP280_TEMPERATURE_OSR (BMP280_OVERSAMP_16X)
#define BMP280_MODE (BMP280_PRESSURE_OSR << 2 | BMP280_TEMPERATURE_OSR << 5 | BMP280_NORMAL_MODE)
#define BMP280_SLAVE_ADDRESS_0x76 0x76
#define BMP280_SLAVE_ADDRESS_0x77 0x77
/*校準參數*/
#define BMP280_DIG_T1_LSB_REG 0x88
#define BMP280_DIG_T1_MSB_REG 0x89
#define BMP280_DIG_T2_LSB_REG 0x8A
#define BMP280_DIG_T2_MSB_REG 0x8B
#define BMP280_DIG_T3_LSB_REG 0x8C
#define BMP280_DIG_T3_MSB_REG 0x8D
#define BMP280_DIG_P1_LSB_REG 0x8E
#define BMP280_DIG_P1_MSB_REG 0x8F
#define BMP280_DIG_P2_LSB_REG 0x90
#define BMP280_DIG_P2_MSB_REG 0x91
#define BMP280_DIG_P3_LSB_REG 0x92
#define BMP280_DIG_P3_MSB_REG 0x93
#define BMP280_DIG_P4_LSB_REG 0x94
#define BMP280_DIG_P4_MSB_REG 0x95
#define BMP280_DIG_P5_LSB_REG 0x96
#define BMP280_DIG_P5_MSB_REG 0x97
#define BMP280_DIG_P6_LSB_REG 0x98
#define BMP280_DIG_P6_MSB_REG 0x99
#define BMP280_DIG_P7_LSB_REG 0x9A
#define BMP280_DIG_P7_MSB_REG 0x9B
#define BMP280_DIG_P8_LSB_REG 0x9C
#define BMP280_DIG_P8_MSB_REG 0x9D
#define BMP280_DIG_P9_LSB_REG 0x9E
#define BMP280_DIG_P9_MSB_REG 0x9F
#define BMP280_CHIPID_REG 0xD0 /*晶片ID寄存器*/
#define BMP280_RESET_REG 0xE0 /*軟重置寄存器*/
#define BMP280_STATUS_REG 0xF3 /*狀態寄存器*/
#define BMP280_CTRLMEAS_REG 0xF4 /*控制測量寄存器*/
#define BMP280_CONFIG_REG 0xF5 /*配置寄存器*/
#define BMP280_PRESSURE_MSB_REG 0xF7 /*壓力MSB寄存器*/
#define BMP280_PRESSURE_LSB_REG 0xF8 /*壓力LSB寄存器*/
#define BMP280_PRESSURE_XLSB_REG 0xF9 /*壓力XLSB寄存器*/
#define BMP280_TEMPERATURE_MSB_REG 0xFA /*溫度MSB寄存器*/
#define BMP280_TEMPERATURE_LSB_REG 0xFB /*溫度LSB寄存器*/
#define BMP280_TEMPERATURE_XLSB_REG 0xFC /*溫度XLSB寄存器*/
#define BMP280_SLEEP_MODE (0x00)
#define BMP280_FORCED_MODE (0x01)
#define BMP280_NORMAL_MODE (0x03)
#define BMP280_TEMPERATURE_CALIB_DIG_T1_LSB_REG (0x88)
#define BMP280_PRESSURE_TEMPERATURE_CALIB_DATA_LENGTH (24)
#define BMP280_DATA_FRAME_SIZE (6)
#define BMP280_OVERSAMP_SKIPPED (0x00)
#define BMP280_OVERSAMP_1X (0x01)
#define BMP280_OVERSAMP_2X (0x02)
#define BMP280_OVERSAMP_4X (0x03)
#define BMP280_OVERSAMP_8X (0x04)
#define BMP280_OVERSAMP_16X (0x05)
#define CONST_PF 0.1902630958
//(1/5.25588f) 壓力因子
#define FIX_TEMP 25
// 固定溫度。ASL 是壓力和溫度的函數,但由於溫度變化太大(稍微吹一下就會下降5度),會影響ASL的估算。
// 簡而言之:調整溫度變化的影響反而弊大於利。
typedef struct
{
uint16_t dig_T1;/* 校準T1數據 */
int16_t dig_T2; /* 校準T2數據 */
int16_t dig_T3; /* 校準T3數據 */
uint16_t dig_P1;/* 校準P1數據 */
int16_t dig_P2; /* 校準P2數據 */
int16_t dig_P3; /* 校準P3數據 */
int16_t dig_P4; /* 校準P4數據 */
int16_t dig_P5; /* 校準P5數據 */
int16_t dig_P6; /* 校準P6數據 */
int16_t dig_P7; /* 校準P7數據 */
int16_t dig_P8; /* 校準P8數據 */
int16_t dig_P9; /* 校準P9數據 */
int t_fine; /* 校準t_fine數據 */
} bmp280Calib;
uint8_t msb , lsb , xlsb;
float var1 , var2;
bmp280Calib bmp280Cal;
uint8_t BMP280_Init(void)
{
uint8_t bmp280_id;
uint8_t tmp[1];
printf("BMP280_Init.\n");
Fake_I2C_Read_Datas_PTB5_PTB4(BMP280_SLAVE_ADDRESS_0x77 , BMP280_CHIPID_REG, 1, &bmp280_id);
printf("bmp280_id = 0x%x\n" , bmp280_id);
Fake_I2C_Read_Datas_PTB5_PTB4(BMP280_SLAVE_ADDRESS_0x77, BMP280_DIG_T1_LSB_REG , 24 , (uint8_t *)&bmp280Cal);
tmp[0] = BMP280_MODE;
Fake_I2C_Write_Reg_Datas_PTB5_PTB4(BMP280_SLAVE_ADDRESS_0x77 , BMP280_CTRLMEAS_REG , 1 , tmp);
tmp[0] = 5 << 2;
Fake_I2C_Write_Reg_Datas_PTB5_PTB4(BMP280_SLAVE_ADDRESS_0x77 , BMP280_CONFIG_REG , 1 , tmp);
return bmp280_id;
}
將BMP280連接到開發板,觀察BMP280的讀數:

但是發現了一個問題,使用 printf 函數無法打印浮點數,只能通過整數型方式強制轉型,並且使用 abs() 函數會導致程式卡死:
BMP280_Read_Pressure_Tempature(&bmp280_pres , &bmp280_temp);
asl = BMP280PressureToAltitude(&bmp280_pres);
printf("pres_bmp280 = %d.%-3d , temp_bmp280 = %d.%-3d , asl = %d.%-3d\n" ,
(int)bmp280_pres , ((int)(bmp280_pres * 1000)) % 1000 ,
(int)bmp280_temp , ((int)(bmp280_temp * 1000)) % 1000 ,
(int)asl , ((int)(asl * 1000)) % 1000
);
這個原因跟編譯器和編譯器選項有關,不深究。
1. 模擬SPI
由於開發板的硬體SPI波形調試一直不順利:

在八位資料前有一個原因不明的時鐘上升沿,因此使用模擬SPI:
模擬 SPI 實現函數:
#define LPSPI0_BUFFER_NUM 2
uint8_t lpspi0_tx_buffer[LPSPI0_BUFFER_NUM] = {0xaa , 0xab};
uint8_t lpspi0_rx_buffer[LPSPI0_BUFFER_NUM] = {0};
#define SPITFTLCD24_RESET_HIGH Siul2_Dio_Ip_WritePin(FAKE_RST_PORT , FAKE_RST_PIN , 1);
#define SPITFTLCD24_RESET_LOW Siul2_Dio_Ip_WritePin(FAKE_RST_PORT , FAKE_RST_PIN , 0);
#define SPITFTLCD24_A0_HIGH Siul2_Dio_Ip_WritePin(FAKE_A0_PORT , FAKE_A0_PIN , 1);
#define SPITFTLCD24_A0_LOW Siul2_Dio_Ip_WritePin(FAKE_A0_PORT , FAKE_A0_PIN , 0);
#define SPITFTLCD24_CS_HIGH Siul2_Dio_Ip_WritePin(FAKE_SPI_CS_PORT , FAKE_SPI_CS_PIN , 1);
#define SPITFTLCD24_CS_LOW Siul2_Dio_Ip_WritePin(FAKE_SPI_CS_PORT , FAKE_SPI_CS_PIN , 0);
#define SPITFTLCD24_MOSI_HIGH Siul2_Dio_Ip_WritePin(FAKE_SPI_MOSI_PORT , FAKE_SPI_MOSI_PIN , 1);
#define SPITFTLCD24_MOSI_LOW Siul2_Dio_Ip_WritePin(FAKE_SPI_MOSI_PORT , FAKE_SPI_MOSI_PIN , 0);
#define SPITFTLCD24_CLK_HIGH Siul2_Dio_Ip_WritePin(FAKE_SPI_CLK_PORT , FAKE_SPI_CLK_PIN , 1);
#define SPITFTLCD24_CLK_LOW Siul2_Dio_Ip_WritePin(FAKE_SPI_CLK_PORT , FAKE_SPI_CLK_PIN , 0);
#define SPITFTLCD24_COLUMN_NUMBER 240
#define SPITFTLCD24_LINE_NUMBER 320
#define SPITFTLCD24_COLUMN_OFFSET 0
#define RED 0xf800
#define GREEN 0x07e0
#define BLUE 0x001f
#define CYAN 0x07ff
#define WHITE 0xffff
#define BLACK 0
void SPITFTLCD24_SEND_CMD(unsigned char o_command)
{
uint8_t i;
SPITFTLCD24_A0_LOW;
SPITFTLCD24_CS_LOW;
SPITFTLCD24_CLK_HIGH;
for(i = 0; i < 8; i++)
{
SPITFTLCD24_CLK_LOW;
if(o_command & 0x80)
{
SPITFTLCD24_MOSI_HIGH;
}
else
{
SPITFTLCD24_MOSI_LOW;
}
o_command <<= 1;
SPITFTLCD24_CLK_HIGH;
}
SPITFTLCD24_CLK_HIGH;
SPITFTLCD24_CS_HIGH;
}
void SPITFTLCD24_SEND_DATA(unsigned char o_data)
{
uint8_t i;
SPITFTLCD24_A0_HIGH;
SPITFTLCD24_CS_LOW;
for(i = 0; i < 8; i++)
{
SPITFTLCD24_CLK_LOW;
if(o_data & 0x80)
{
SPITFTLCD24_MOSI_HIGH;
}
else
{
SPITFTLCD24_MOSI_LOW;
}
o_data <<= 1;
SPITFTLCD24_CLK_HIGH;
}
SPITFTLCD24_CS_HIGH;
}
void SPITFTLCD24_Clear(void)
{
uint32_t row, column;
SPITFTLCD24_SEND_CMD(0x2a); // 設定列地址
SPITFTLCD24_SEND_DATA(0x00); // 起始列
SPITFTLCD24_SEND_DATA(0x00);
SPITFTLCD24_SEND_DATA(0x00); // 結束列
SPITFTLCD24_SEND_DATA(0xF0);
SPITFTLCD24_SEND_CMD(0x2b); // 設定行地址
SPITFTLCD24_SEND_DATA(0x00); // 起始行
SPITFTLCD24_SEND_DATA(0x00);
SPITFTLCD24_SEND_DATA(0x01); // 結束行
SPITFTLCD24_SEND_DATA(0x40);
SPITFTLCD24_SEND_CMD(0x2C); // 記憶體寫入
for(row = 0; row < SPITFTLCD24_LINE_NUMBER; row++)
{
for(column = 0; column < SPITFTLCD24_COLUMN_NUMBER; column++)
{
SPITFTLCD24_SEND_DATA(0xFF);
SPITFTLCD24_SEND_DATA(0xFF);
}
}
}
void SPITFTLCD24_Full(uint16_t color)
{
uint32_t row, column;
SPITFTLCD24_SEND_CMD(0x2a); // 設定列地址
SPITFTLCD24_SEND_DATA(0x00); // 起始列
SPITFTLCD24_SEND_DATA(0x00);
SPITFTLCD24_SEND_DATA(0x00); // 結束列
SPITFTLCD24_SEND_DATA(0xF0);
SPITFTLCD24_SEND_CMD(0x2b); // 設定行地址
SPITFTLCD24_SEND_DATA(0x00); // 起始行
SPITFTLCD24_SEND_DATA(0x00);
SPITFTLCD24_SEND_DATA(0x01); // 結束行
SPITFTLCD24_SEND_DATA(0x40);
SPITFTLCD24_SEND_CMD(0x2C); // 記憶體寫入
for(row = 0; row < SPITFTLCD24_LINE_NUMBER; row++)
{
for(column = 0; column < SPITFTLCD24_COLUMN_NUMBER; column++)
{
SPITFTLCD24_SEND_DATA(color >> 8);
SPITFTLCD24_SEND_DATA(color);
}
}
}
void SPITFTLCD24_Init(void)
{
SPITFTLCD24_RESET_LOW;
Pit0_Delay_ms(10);
SPITFTLCD24_RESET_HIGH;
Pit0_Delay_ms(120);
SPITFTLCD24_SEND_CMD(0x01); // 軟體重置
Pit0_Delay_ms(120);
SPITFTLCD24_SEND_CMD(0x11); // 退出睡眠模式
Pit0_Delay_ms(120);
SPITFTLCD24_SEND_CMD(0x3A); // 65k 模式
SPITFTLCD24_SEND_DATA(0x05);
SPITFTLCD24_SEND_CMD(0xC5); // VCOM
SPITFTLCD24_SEND_DATA(0x1A);
SPITFTLCD24_SEND_CMD(0x36); // 設定方向
SPITFTLCD24_SEND_DATA(0x00);
SPITFTLCD24_SEND_CMD(0xb2); // Porch 設定
SPITFTLCD24_SEND_DATA(0x05);
SPITFTLCD24_SEND_DATA(0x05);
SPITFTLCD24_SEND_DATA(0x00);
SPITFTLCD24_SEND_DATA(0x33);
SPITFTLCD24_SEND_DATA(0x33);
SPITFTLCD24_SEND_CMD(0xb7); // 閘極控制
SPITFTLCD24_SEND_DATA(0x05);
SPITFTLCD24_SEND_CMD(0xBB); // VCOM
SPITFTLCD24_SEND_DATA(0x3F);
SPITFTLCD24_SEND_CMD(0xC0); // 電源控制
SPITFTLCD24_SEND_DATA(0x2c);
SPITFTLCD24_SEND_CMD(0xC2); // VDV 和 VRH 命令啟用
SPITFTLCD24_SEND_DATA(0x01);
SPITFTLCD24_SEND_CMD(0xC3); // VRH 設定
SPITFTLCD24_SEND_DATA(0x0F);
SPITFTLCD24_SEND_CMD(0xC4); // VDV 設定
SPITFTLCD24_SEND_DATA(0x20);
SPITFTLCD24_SEND_CMD(0xC6); // 正常模式下的幀率控制
SPITFTLCD24_SEND_DATA(0X01);
SPITFTLCD24_SEND_CMD(0xd0); // 電源控制 1
SPITFTLCD24_SEND_DATA(0xa4);
SPITFTLCD24_SEND_DATA(0xa1);
SPITFTLCD24_SEND_CMD(0xE8); // 電源控制 1
SPITFTLCD24_SEND_DATA(0x03);
SPITFTLCD24_SEND_CMD(0xE9); // 均衡時間控制
SPITFTLCD24_SEND_DATA(0x09);
SPITFTLCD24_SEND_DATA(0x09);
SPITFTLCD24_SEND_DATA(0x08);
SPITFTLCD24_SEND_CMD(0xE0); // 設定伽瑪
SPITFTLCD24_SEND_DATA(0xD0);
SPITFTLCD24_SEND_DATA(0x05);
SPITFTLCD24_SEND_DATA(0x09);
SPITFTLCD24_SEND_DATA(0x09);
SPITFTLCD24_SEND_DATA(0x08);
SPITFTLCD24_SEND_DATA(0x14);
SPITFTLCD24_SEND_DATA(0x28);
SPITFTLCD24_SEND_DATA(0x33);
SPITFTLCD24_SEND_DATA(0x3F);
SPITFTLCD24_SEND_DATA(0x07);
SPITFTLCD24_SEND_DATA(0x13);
SPITFTLCD24_SEND_DATA(0x14);
SPITFTLCD24_SEND_DATA(0x28);
SPITFTLCD24_SEND_DATA(0x30);
SPITFTLCD24_SEND_CMD(0xE1); // 設定伽瑪
SPITFTLCD24_SEND_DATA(0xD0);
SPITFTLCD24_SEND_DATA(0x05);
SPITFTLCD24_SEND_DATA(0x09);
SPITFTLCD24_SEND_DATA(0x09);
SPITFTLCD24_SEND_DATA(0x08);
SPITFTLCD24_SEND_DATA(0x03);
SPITFTLCD24_SEND_DATA(0x24);
SPITFTLCD24_SEND_DATA(0x32);
SPITFTLCD24_SEND_DATA(0x32);
SPITFTLCD24_SEND_DATA(0x3B);
SPITFTLCD24_SEND_DATA(0x14);
SPITFTLCD24_SEND_DATA(0x13);
SPITFTLCD24_SEND_DATA(0x28);
SPITFTLCD24_SEND_DATA(0x2F);
SPITFTLCD24_SEND_CMD(0x20);
Pit0_Delay_ms(120);
SPITFTLCD24_SEND_CMD(0x29);
}
但是效果不理想,刷屏太慢,因此還在想其他的辦法。
2. CAN 通訊
調試CAN通信這個環節不是很順利,即使到最後能輸出波形,但仍然無法與其他廠商的MCU成功進行CAN通信。
調試CAN通信需要先啟用前置模組Siul2_Icu模組,並添加兩個通道:
新增硬體通道16和17:
引腳則是選用PTA6和PTA7作為CAN0的輸出:

PTA6和PTA7位於J31母座上。
對於FlexCAN的配置則是參考論壇的帖子進行的,自己改了一些參數,設定1MB長度,Payload 8字節,協議時鐘和波特率參數則是直接照抄:
將PTA6和PTA7引腳與CAN收發模組進行連接:
初始化和CAN傳送程式碼如下:
Siul2_Icu_Ip_Init(0, &Siul2_Icu_Ip_0_Config_PB);
Siul2_Icu_Ip_EnableInterrupt(0, (*Siul2_Icu_Ip_0_Config_PB.pChannelsConfig)[0].hwChannel);
Siul2_Icu_Ip_EnableInterrupt(0, (*Siul2_Icu_Ip_0_Config_PB.pChannelsConfig)[1].hwChannel);
Siul2_Icu_Ip_EnableNotification(0, (*Siul2_Icu_Ip_0_Config_PB.pChannelsConfig)[0].hwChannel);
Siul2_Icu_Ip_EnableNotification(0, (*Siul2_Icu_Ip_0_Config_PB.pChannelsConfig)[1].hwChannel);
FlexCAN_Ip_Init(0, &FlexCAN_State0, &FlexCAN_Config0);
FlexCAN_Ip_SetStartMode(0);
while(1)
{
FlexCAN_Ip_Send(0, TX_MB_IDX, &CAN_NODE_0_TX_MB0_Config, FLEXCAN_MSG_ID, (uint8_t *)&dummyData);
Pit0_Delay_ms(100);
printf("FlexCAN_Ip_Send.\n");
}
將示波器的探頭接入CANH和CANL兩個輸出引腳:

文章來自「S32K312 開發板評測活動」測評者:李明
歡迎在部落格文章下方留言評論,我們會及時回覆您的問題。
如有更多需求,歡迎聯繫大聯大世平集團 ATU 部門:atu.sh@wpi-group.com 作者:WPIg
更多資訊,請掃碼關注我們!

評論