Tinkering TI MSP430F5529
|
USCI – SPI – I2C Example 2
We covered most of the stuffs that are needed to be understood and applied for using USCI in SPI and I2C modes. However, we didn’t see any SPI read operation in our last example. This example is meant to eliminate that missing stuff while allowing us to explore and practice USCI modules further. It is yet another over-simplified example. A MAX6675 SPI-based thermocouple-digital converter is read using a MSP430’s USCI in SPI mode while an I2C-based SSD1306 OLED display is used to display the temperature read from the thermocouple.
Code Example
MAX6675.h
#include "driverlib.h" #include "delay.h" #define MOSI_port GPIO_PORT_P3 #define MISO_port GPIO_PORT_P3 #define CLK_port GPIO_PORT_P2 #define CS_port GPIO_PORT_P3 #define MOSI_pin GPIO_PIN3 #define MISO_pin GPIO_PIN4 #define CLK_pin GPIO_PIN7 #define CS_pin GPIO_PIN2 #define MOSI_pin_high() GPIO_setOutputHighOnPin(MOSI_port, MOSI_pin) #define MOSI_pin_low() GPIO_setOutputLowOnPin(MOSI_port, MOSI_pin) #define get_MISO_pin() GPIO_getInputPinValue(MISO_port, MISO_pin) #define CLK_pin_high() GPIO_setOutputHighOnPin(CLK_port, CLK_pin) #define CLK_pin_low() GPIO_setOutputLowOnPin(CLK_port, CLK_pin) #define CS_pin_high() GPIO_setOutputHighOnPin(CS_port, CS_pin) #define CS_pin_low() GPIO_setOutputLowOnPin(CS_port, CS_pin) #define T_min 0 #define T_max 1024 #define count_max 4096 #define no_of_pulses 16 #define deg_C 0 #define deg_F 1 #define tmp_K 2 #define open_contact 0x04 #define close_contact 0x00 #define scalar_deg_C 0.25 #define scalar_deg_F_1 1.8 #define scalar_deg_F_2 32.0 #define scalar_tmp_K 273.0 #define no_of_samples 16 void SPI_DIO_init(void); void USCI_SPI_init(void); void MAX6675_init(void); unsigned char MAX6675_get_ADC(unsigned int *ADC_data); float MAX6675_get_T(unsigned int ADC_value, unsigned char T_unit);
MAX6675.c
#include "MAX6675.h" void SPI_DIO_init(void) { GPIO_setAsPeripheralModuleFunctionInputPin(MISO_port, MISO_pin); GPIO_setAsPeripheralModuleFunctionOutputPin(MOSI_port, MOSI_pin); GPIO_setAsPeripheralModuleFunctionOutputPin(CLK_port, CLK_pin); GPIO_setAsOutputPin(CS_port, CS_pin); GPIO_setDriveStrength(CS_port, CS_pin, GPIO_FULL_OUTPUT_DRIVE_STRENGTH); } void USCI_SPI_init(void) { USCI_A_SPI_initMasterParam SPI_param = {0}; SPI_DIO_init(); SPI_param.selectClockSource = USCI_A_SPI_CLOCKSOURCE_SMCLK; SPI_param.clockSourceFrequency = UCS_getSMCLK(); SPI_param.desiredSpiClock = 1000000; SPI_param.msbFirst = USCI_A_SPI_MSB_FIRST; SPI_param.clockPhase = USCI_A_SPI_PHASE_DATA_CAPTURED_ONFIRST_CHANGED_ON_NEXT; SPI_param.clockPolarity = USCI_A_SPI_CLOCKPOLARITY_INACTIVITY_LOW; USCI_A_SPI_initMaster(USCI_A0_BASE, &SPI_param); USCI_A_SPI_enable(USCI_A0_BASE); } void MAX6675_init(void) { USCI_SPI_init(); } unsigned char MAX6675_get_ADC(unsigned int *ADC_data) { unsigned char lb = 0; unsigned char hb = 0; unsigned char samples = no_of_samples; unsigned int temp_data = 0; unsigned long avg_value = 0; while(samples > 0) { CS_pin_low(); USCI_A_SPI_transmitData(USCI_A0_BASE, 0x00); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); hb = USCI_A_SPI_receiveData(USCI_A0_BASE); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); USCI_B_SPI_transmitData(USCI_A0_BASE, 0x00); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); lb = USCI_A_SPI_receiveData(USCI_A0_BASE); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); CS_pin_high(); temp_data = hb; temp_data <> 4); if((temp_data & 0x04) == close_contact) { *ADC_data = (temp_data >> 3); return close_contact; } else { *ADC_data = (count_max + 1); return open_contact; } } float MAX6675_get_T(unsigned int ADC_value, unsigned char T_unit) { float tmp = 0.0; tmp = (((float)ADC_value) * scalar_deg_C); switch(T_unit) { case deg_F: { tmp *= scalar_deg_F_1; tmp += scalar_deg_F_2; break; } case tmp_K: { tmp += scalar_tmp_K; break; } default: { break; } } return tmp; }
SSD1306.h
#include "driverlib.h" #include "delay.h" #define I2C_port GPIO_PORT_P3 #define I2C_SDA_pin GPIO_PIN0 #define I2C_SCL_pin GPIO_PIN1 #define SSD1306_I2C_Address 0x3C #define DAT 0x60 #define CMD 0x00 #define Set_Lower_Column_Start_Address_CMD 0x00 #define Set_Higher_Column_Start_Address_CMD 0x10 #define Set_Memory_Addressing_Mode_CMD 0x20 #define Set_Column_Address_CMD 0x21 #define Set_Page_Address_CMD 0x22 #define Set_Display_Start_Line_CMD 0x40 #define Set_Contrast_Control_CMD 0x81 #define Set_Charge_Pump_CMD 0x8D #define Set_Segment_Remap_CMD 0xA0 #define Set_Entire_Display_ON_CMD 0xA4 #define Set_Normal_or_Inverse_Display_CMD 0xA6 #define Set_Multiplex_Ratio_CMD 0xA8 #define Set_Display_ON_or_OFF_CMD 0xAE #define Set_Page_Start_Address_CMD 0xB0 #define Set_COM_Output_Scan_Direction_CMD 0xC0 #define Set_Display_Offset_CMD 0xD3 #define Set_Display_Clock_CMD 0xD5 #define Set_Pre_charge_Period_CMD 0xD9 #define Set_Common_HW_Config_CMD 0xDA #define Set_VCOMH_Level_CMD 0xDB #define Set_NOP_CMD 0xE3 #define Horizontal_Addressing_Mode 0x00 #define Vertical_Addressing_Mode 0x01 #define Page_Addressing_Mode 0x02 #define Disable_Charge_Pump 0x00 #define Enable_Charge_Pump 0x04 #define Column_Address_0_Mapped_to_SEG0 0x00 #define Column_Address_0_Mapped_to_SEG127 0x01 #define Normal_Display 0x00 #define Entire_Display_ON 0x01 #define Non_Inverted_Display 0x00 #define Inverted_Display 0x01 #define Display_OFF 0x00 #define Display_ON 0x01 #define Scan_from_COM0_to_63 0x00 #define Scan_from_COM63_to_0 0x08 #define x_size 128 #define x_max x_size #define x_min 0 #define y_size 32 #define y_max 8 #define y_min 0 #define ON 1 #define OFF 0 #define YES 1 #define NO 0 #define ROUND 1 #define SQUARE 0 #define NUM 1 #define CHR 0 #define buffer_size 512//(x_max * y_max) unsigned char buffer[buffer_size]; void swap(signed int *a, signed int *b); void I2C_DIO_init(void); void USCI_I2C_init(void); void OLED_init(void); void OLED_write(unsigned char value, unsigned char control_byte); void OLED_gotoxy(unsigned char x_pos, unsigned char y_pos); void OLED_fill(unsigned char bmp_data); void OLED_clear_screen(void); void OLED_clear_buffer(void); void OLED_cursor(unsigned char x_pos, unsigned char y_pos); void print_char(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, unsigned char ch); void print_string(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, unsigned char *ch); void print_chr(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, signed int value); void print_int(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, signed long value); void print_decimal(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, unsigned int value, unsigned char points); void print_float(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, float value, unsigned char points); void draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img); void draw_pixel(unsigned char x_pos, unsigned char y_pos, unsigned char colour); void draw_line(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char colour); void draw_V_line(signed int x1, signed int y1, signed int y2, unsigned colour); void draw_H_line(signed int x1, signed int x2, signed int y1, unsigned colour); void draw_triangle(signed int x1, signed int y1, signed int x2, signed int y2, signed int x3, signed int y3, unsigned char fill, unsigned int colour); void draw_rectangle(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char fill, unsigned char colour, unsigned char type); void draw_rectangle(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char fill, unsigned char colour, unsigned char type); void draw_circle(signed int xc, signed int yc, signed int radius, unsigned char fill, unsigned char colour);
SSD1306.c
#include "SSD1306.h" static const unsigned char font_regular[92][6] = { 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // sp 0x00, 0x00, 0x00, 0x2f, 0x00, 0x00, // ! 0x00, 0x00, 0x07, 0x00, 0x07, 0x00, // " 0x00, 0x14, 0x7f, 0x14, 0x7f, 0x14, // # 0x00, 0x24, 0x2a, 0x7f, 0x2a, 0x12, // $ 0x00, 0x62, 0x64, 0x08, 0x13, 0x23, // % 0x00, 0x36, 0x49, 0x55, 0x22, 0x50, // & 0x00, 0x00, 0x05, 0x03, 0x00, 0x00, // ' 0x00, 0x00, 0x1c, 0x22, 0x41, 0x00, // ( 0x00, 0x00, 0x41, 0x22, 0x1c, 0x00, // ) 0x00, 0x14, 0x08, 0x3E, 0x08, 0x14, // * 0x00, 0x08, 0x08, 0x3E, 0x08, 0x08, // + 0x00, 0x00, 0x00, 0xA0, 0x60, 0x00, // , 0x00, 0x08, 0x08, 0x08, 0x08, 0x08, // - 0x00, 0x00, 0x60, 0x60, 0x00, 0x00, // . 0x00, 0x20, 0x10, 0x08, 0x04, 0x02, // / 0x00, 0x3E, 0x51, 0x49, 0x45, 0x3E, // 0 0x00, 0x00, 0x42, 0x7F, 0x40, 0x00, // 1 0x00, 0x42, 0x61, 0x51, 0x49, 0x46, // 2 0x00, 0x21, 0x41, 0x45, 0x4B, 0x31, // 3 0x00, 0x18, 0x14, 0x12, 0x7F, 0x10, // 4 0x00, 0x27, 0x45, 0x45, 0x45, 0x39, // 5 0x00, 0x3C, 0x4A, 0x49, 0x49, 0x30, // 6 0x00, 0x01, 0x71, 0x09, 0x05, 0x03, // 7 0x00, 0x36, 0x49, 0x49, 0x49, 0x36, // 8 0x00, 0x06, 0x49, 0x49, 0x29, 0x1E, // 9 0x00, 0x00, 0x36, 0x36, 0x00, 0x00, // : 0x00, 0x00, 0x56, 0x36, 0x00, 0x00, // ; 0x00, 0x08, 0x14, 0x22, 0x41, 0x00, // 0x00, 0x02, 0x01, 0x51, 0x09, 0x06, // ? 0x00, 0x32, 0x49, 0x59, 0x51, 0x3E, // @ 0x00, 0x7C, 0x12, 0x11, 0x12, 0x7C, // A 0x00, 0x7F, 0x49, 0x49, 0x49, 0x36, // B 0x00, 0x3E, 0x41, 0x41, 0x41, 0x22, // C 0x00, 0x7F, 0x41, 0x41, 0x22, 0x1C, // D 0x00, 0x7F, 0x49, 0x49, 0x49, 0x41, // E 0x00, 0x7F, 0x09, 0x09, 0x09, 0x01, // F 0x00, 0x3E, 0x41, 0x49, 0x49, 0x7A, // G 0x00, 0x7F, 0x08, 0x08, 0x08, 0x7F, // H 0x00, 0x00, 0x41, 0x7F, 0x41, 0x00, // I 0x00, 0x20, 0x40, 0x41, 0x3F, 0x01, // J 0x00, 0x7F, 0x08, 0x14, 0x22, 0x41, // K 0x00, 0x7F, 0x40, 0x40, 0x40, 0x40, // L 0x00, 0x7F, 0x02, 0x0C, 0x02, 0x7F, // M 0x00, 0x7F, 0x04, 0x08, 0x10, 0x7F, // N 0x00, 0x3E, 0x41, 0x41, 0x41, 0x3E, // O 0x00, 0x7F, 0x09, 0x09, 0x09, 0x06, // P 0x00, 0x3E, 0x41, 0x51, 0x21, 0x5E, // Q 0x00, 0x7F, 0x09, 0x19, 0x29, 0x46, // R 0x00, 0x46, 0x49, 0x49, 0x49, 0x31, // S 0x00, 0x01, 0x01, 0x7F, 0x01, 0x01, // T 0x00, 0x3F, 0x40, 0x40, 0x40, 0x3F, // U 0x00, 0x1F, 0x20, 0x40, 0x20, 0x1F, // V 0x00, 0x3F, 0x40, 0x38, 0x40, 0x3F, // W 0x00, 0x63, 0x14, 0x08, 0x14, 0x63, // X 0x00, 0x07, 0x08, 0x70, 0x08, 0x07, // Y 0x00, 0x61, 0x51, 0x49, 0x45, 0x43, // Z 0x00, 0x00, 0x7F, 0x41, 0x41, 0x00, // [ 0x00, 0x02, 0x04, 0x08, 0x10, 0x20, // \92 0x00, 0x00, 0x41, 0x41, 0x7F, 0x00, // ] 0x00, 0x04, 0x02, 0x01, 0x02, 0x04, // ^ 0x00, 0x40, 0x40, 0x40, 0x40, 0x40, // _ 0x00, 0x00, 0x01, 0x02, 0x04, 0x00, // ' 0x00, 0x20, 0x54, 0x54, 0x54, 0x78, // a 0x00, 0x7F, 0x48, 0x44, 0x44, 0x38, // b 0x00, 0x38, 0x44, 0x44, 0x44, 0x20, // c 0x00, 0x38, 0x44, 0x44, 0x48, 0x7F, // d 0x00, 0x38, 0x54, 0x54, 0x54, 0x18, // e 0x00, 0x08, 0x7E, 0x09, 0x01, 0x02, // f 0x00, 0x18, 0xA4, 0xA4, 0xA4, 0x7C, // g 0x00, 0x7F, 0x08, 0x04, 0x04, 0x78, // h 0x00, 0x00, 0x44, 0x7D, 0x40, 0x00, // i 0x00, 0x40, 0x80, 0x84, 0x7D, 0x00, // j 0x00, 0x7F, 0x10, 0x28, 0x44, 0x00, // k 0x00, 0x00, 0x41, 0x7F, 0x40, 0x00, // l 0x00, 0x7C, 0x04, 0x18, 0x04, 0x78, // m 0x00, 0x7C, 0x08, 0x04, 0x04, 0x78, // n 0x00, 0x38, 0x44, 0x44, 0x44, 0x38, // o 0x00, 0xFC, 0x24, 0x24, 0x24, 0x18, // p 0x00, 0x18, 0x24, 0x24, 0x18, 0xFC, // q 0x00, 0x7C, 0x08, 0x04, 0x04, 0x08, // r 0x00, 0x48, 0x54, 0x54, 0x54, 0x20, // s 0x00, 0x04, 0x3F, 0x44, 0x40, 0x20, // t 0x00, 0x3C, 0x40, 0x40, 0x20, 0x7C, // u 0x00, 0x1C, 0x20, 0x40, 0x20, 0x1C, // v 0x00, 0x3C, 0x40, 0x30, 0x40, 0x3C, // w 0x00, 0x44, 0x28, 0x10, 0x28, 0x44, // x 0x00, 0x1C, 0xA0, 0xA0, 0xA0, 0x7C, // y 0x00, 0x44, 0x64, 0x54, 0x4C, 0x44, // z 0x14, 0x14, 0x14, 0x14, 0x14, 0x14 // horiz lines }; static const unsigned char Number_Font[11][6] = { 0x00, 0x7F, 0x41, 0x41, 0x41, 0x7F, //0 0x00, 0x00, 0x00, 0x41, 0x7F, 0x40, //1 0x00, 0x79, 0x49, 0x49, 0x49, 0x4F, //2 0x00, 0x41, 0x49, 0x49, 0x49, 0x7F, //3 0x00, 0x0F, 0x08, 0x08, 0x08, 0x7F, //4 0x00, 0x4F, 0x49, 0x49, 0x49, 0x79, //5 0x00, 0x7F, 0x48, 0x48, 0x48, 0x78, //6 0x00, 0x00, 0x01, 0x01, 0x01, 0x7F, //7 0x00, 0x7F, 0x49, 0x49, 0x49, 0x7F, //8 0x00, 0x0F, 0x09, 0x09, 0x09, 0x7F, //9 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 //spc }; void swap(signed int *a, signed int *b) { signed int temp = 0x0000; temp = *b; *b = *a; *a = temp; } void I2C_DIO_init(void) { GPIO_setAsPeripheralModuleFunctionOutputPin(I2C_port, (I2C_SDA_pin | I2C_SCL_pin)); } void USCI_I2C_init(void) { USCI_B_I2C_initMasterParam I2C_param = {0}; I2C_DIO_init(); I2C_param.selectClockSource = USCI_B_I2C_CLOCKSOURCE_SMCLK; I2C_param.i2cClk = UCS_getSMCLK(); I2C_param.dataRate = USCI_B_I2C_SET_DATA_RATE_400KBPS; USCI_B_I2C_initMaster(USCI_B0_BASE, &I2C_param); USCI_B_I2C_enable(USCI_B0_BASE); } void OLED_init(void) { USCI_I2C_init(); delay_ms(100); OLED_write((Set_Display_ON_or_OFF_CMD | Display_OFF), CMD); OLED_write(Set_Multiplex_Ratio_CMD, CMD); OLED_write(0x1F, CMD); OLED_write(Set_Display_Offset_CMD, CMD); OLED_write(0x00, CMD); OLED_write(Set_Display_Start_Line_CMD, CMD); OLED_write((Set_Segment_Remap_CMD | Column_Address_0_Mapped_to_SEG127), CMD); OLED_write((Set_COM_Output_Scan_Direction_CMD | Scan_from_COM63_to_0), CMD); OLED_write(Set_Common_HW_Config_CMD, CMD); OLED_write(0x02, CMD); OLED_write(Set_Contrast_Control_CMD, CMD); OLED_write(0x8F, CMD); OLED_write(Set_Entire_Display_ON_CMD, CMD); OLED_write(Set_Normal_or_Inverse_Display_CMD, CMD); OLED_write(Set_Display_Clock_CMD, CMD); OLED_write(0x80, CMD); OLED_write(Set_Pre_charge_Period_CMD, CMD); OLED_write(0x25, CMD); OLED_write(Set_VCOMH_Level_CMD, CMD); OLED_write(0x20, CMD); OLED_write(Set_Page_Address_CMD, CMD); OLED_write(0x00, CMD); OLED_write(0x03, CMD); OLED_write(Set_Page_Start_Address_CMD , CMD); OLED_write(Set_Higher_Column_Start_Address_CMD, CMD); OLED_write(Set_Lower_Column_Start_Address_CMD, CMD); OLED_write(Set_Memory_Addressing_Mode_CMD, CMD); OLED_write(0x02, CMD); OLED_write(Set_Charge_Pump_CMD, CMD); OLED_write(0x14, CMD); OLED_write((Set_Display_ON_or_OFF_CMD | Display_ON), CMD); delay_ms(100); OLED_clear_buffer(); OLED_clear_screen(); } void OLED_write(unsigned char value, unsigned char control_byte) { USCI_B_I2C_setSlaveAddress(USCI_B0_BASE, SSD1306_I2C_Address); USCI_B_I2C_setMode(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_MODE); USCI_B_I2C_masterSendMultiByteStart(USCI_B0_BASE, control_byte); while(!USCI_B_I2C_masterIsStartSent(USCI_B0_BASE)); USCI_B_I2C_masterSendMultiByteFinish(USCI_B0_BASE, value); while(USCI_B_I2C_isBusBusy(USCI_B0_BASE)); } void OLED_gotoxy(unsigned char x_pos, unsigned char y_pos) { OLED_write((Set_Page_Start_Address_CMD + y_pos), CMD); OLED_write(((x_pos & 0x0F) | Set_Lower_Column_Start_Address_CMD), CMD); OLED_write((((x_pos & 0xF0) >> 0x04) | Set_Higher_Column_Start_Address_CMD), CMD); } void OLED_fill(unsigned char bmp_data) { unsigned char x_pos = 0x00; unsigned char page = 0x00; for(page = 0; page < y_max; page++) { OLED_gotoxy(x_min, page); USCI_B_I2C_setSlaveAddress(USCI_B0_BASE, SSD1306_I2C_Address); USCI_B_I2C_setMode(USCI_B0_BASE, USCI_B_I2C_TRANSMIT_MODE); USCI_B_I2C_masterSendMultiByteStart(USCI_B0_BASE, DAT); while(!USCI_B_I2C_masterIsStartSent(USCI_B0_BASE)); for(x_pos = x_min; x_pos < x_max; x_pos++) { USCI_B_I2C_masterSendMultiByteNext(USCI_B0_BASE, bmp_data); } USCI_B_I2C_masterSendMultiByteStop(USCI_B0_BASE); while(USCI_B_I2C_isBusBusy(USCI_B0_BASE)); } } void OLED_clear_screen() { OLED_fill(0x00); } void OLED_clear_buffer() { unsigned int s = 0x0000; for(s = 0; s < buffer_size; s++) { buffer[s] = 0x00; } } void OLED_cursor(unsigned char x_pos, unsigned char y_pos) { unsigned char s = 0x00; if(y_pos != 0x00) { if(x_pos == 1) { OLED_gotoxy(0x00, (y_pos + 0x02)); } else { OLED_gotoxy((0x50 + ((x_pos - 0x02) * 0x06)), (y_pos + 0x02)); } for(s = 0x00; s < 0x06; s++) { OLED_write(0xFF, DAT); } } } void draw_bitmap(unsigned char xb, unsigned char yb, unsigned char xe, unsigned char ye, unsigned char *bmp_img) { unsigned int s = 0x0000; unsigned char x_pos = 0x00; unsigned char y_pos = 0x00; for(y_pos = yb; y_pos <= ye; y_pos++) { OLED_gotoxy(xb, y_pos); for(x_pos = xb; x_pos = 48) && (ch (x_max - 0x06)) { x_pos = 0x00; y_pos++; } OLED_gotoxy(x_pos, y_pos); for(s = 0x00; s = 0x20) && (ch[s] <= 0x7F)); } void print_chr(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, signed int value) { unsigned char ch = 0x00; if(value = 100) && (value = 10) && (value = 0) && (value < 10)) { ch = (value % 10); print_char((x_pos + 6), y_pos, num_reg_state, (48 + ch)); print_char((x_pos + 12), y_pos, num_reg_state, 0x20); print_char((x_pos + 18), y_pos, num_reg_state, 0x20); } } void print_int(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, signed long value) { unsigned char ch = 0x00; if(value = 10000) && ((value = 1000) && (value = 100) && (value = 10) && (value = 0) && (value 1) { ch = ((value % 1000) / 100); print_char((x_pos + 12), y_pos, num_reg_state, (48 + ch)); if(points > 2) { ch = ((value % 100) / 10); print_char((x_pos + 18), y_pos, num_reg_state, (48 + ch)); if(points > 3) { ch = (value % 10); print_char((x_pos + 24), y_pos, num_reg_state, (48 + ch)); } } } } void print_float(unsigned char x_pos, unsigned char y_pos, unsigned char num_reg_state, float value, unsigned char points) { signed long tmp = 0x00; tmp = value; print_int(x_pos, y_pos, num_reg_state, tmp); tmp = ((value - tmp) * 10000); if(tmp = 10000) && (value = 1000) && (value = 100) && (value = 10) && (value < 100)) { print_decimal((x_pos + 18), y_pos, num_reg_state, tmp, points); } else if(value < 10) { print_decimal((x_pos + 12), y_pos, num_reg_state, tmp, points); if((value) < 0) { print_char(x_pos, y_pos, CHR, '-'); } else { print_char(x_pos, y_pos, CHR, ' '); } } } void draw_pixel(unsigned char x_pos, unsigned char y_pos, unsigned char colour) { unsigned char value = 0x00; unsigned char page = 0x00; unsigned char bit_pos = 0x00; page = (y_pos / y_max); bit_pos = (y_pos - (page * y_max)); value = buffer[((page * x_max) + x_pos)]; if((colour & YES) != NO) { value |= (1 << bit_pos); } else { value &= (~(1 << bit_pos)); } buffer[((page * x_max) + x_pos)] = value; OLED_gotoxy(x_pos, page); OLED_write(value, DAT); } void draw_line(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char colour) { signed int dx = 0x0000; signed int dy = 0x0000; signed int stepx = 0x0000; signed int stepy = 0x0000; signed int fraction = 0x0000; dy = (y2 - y1); dx = (x2 - x1); if (dy < 0) { dy = -dy; stepy = -1; } else { stepy = 1; } if (dx < 0) { dx = -dx; stepx = -1; } else { stepx = 1; } dx <<= 1; dy < dy) { fraction = (dy - (dx >> 1)); while (x1 != x2) { if(fraction >= 0) { y1 += stepy; fraction -= dx; } x1 += stepx; fraction += dy; draw_pixel(x1, y1, colour); } } else { fraction = (dx - (dy >> 1)); while (y1 != y2) { if (fraction >= 0) { x1 += stepx; fraction -= dy; } y1 += stepy; fraction += dx; draw_pixel(x1, y1, colour); } } } void draw_V_line(signed int x1, signed int y1, signed int y2, unsigned colour) { if(y1 > y2) { swap(&y1, &y2); } while(y2 > (y1 - 1)) { draw_pixel(x1, y2, colour); y2--; } } void draw_H_line(signed int x1, signed int x2, signed int y1, unsigned colour) { if(x1 > x2) { swap(&x1, &x2); } while(x2 > (x1 - 1)) { draw_pixel(x2, y1, colour); x2--; } } void draw_triangle(signed int x1, signed int y1, signed int x2, signed int y2, signed int x3, signed int y3, unsigned char fill, unsigned int colour) { signed int a = 0; signed int b = 0; signed int sa = 0; signed int sb = 0; signed int yp = 0; signed int last = 0; signed int dx12 = 0; signed int dx23 = 0; signed int dx13 = 0; signed int dy12 = 0; signed int dy23 = 0; signed int dy13 = 0; switch(fill) { case YES: { if(y1 > y2) { swap(&y1, &y2); swap(&x1, &x2); } if(y2 > y3) { swap(&y3, &y2); swap(&x3, &x2); } if(y1 > y2) { swap(&y1, &y2); swap(&x1, &x2); } if(y1 == y3) { a = b = x1; if(x2 b) { b = x2; } if(x2 b) { b = x3; } draw_H_line(a, (a + (b - (a + 1))), y1, colour); return; } dx12 = (x2 - x1); dy12 = (y2 - y1); dx13 = (x3 - x1); dy13 = (y3 - y1); dx23 = (x3 - x2); dy23 = (y3 - y2); sa = 0, sb = 0; if(y2 == y3) { last = y2; } else { last = (y2 - 1); } for(yp = y1; yp b) { swap(&a, &b); } draw_H_line(a, (a + (b - (a + 1))), yp, colour); } sa = (dx23 * (yp - y2)); sb = (dx13 * (yp - y1)); for(; yp b) { swap(&a, &b); } draw_H_line(a, (a + (b - (a + 1))), yp, colour); } break; } default: { draw_line(x1, y1, x2, y2, colour); draw_line(x2, y2, x3, y3, colour); draw_line(x3, y3, x1, y1, colour); break; } } } void draw_rectangle(signed int x1, signed int y1, signed int x2, signed int y2, unsigned char fill, unsigned char colour, unsigned char type) { unsigned short i = 0x00; unsigned short xmin = 0x00; unsigned short xmax = 0x00; unsigned short ymin = 0x00; unsigned short ymax = 0x00; if(fill != NO) { if(x1 < x2) { xmin = x1; xmax = x2; } else { xmin = x2; xmax = x1; } if(y1 < y2) { ymin = y1; ymax = y2; } else { ymin = y2; ymax = y1; } for(; xmin <= xmax; ++xmin) { for(i = ymin; i <= ymax; ++i) { draw_pixel(xmin, i, colour); } } } else { draw_line(x1, y1, x2, y1, colour); draw_line(x1, y2, x2, y2, colour); draw_line(x1, y1, x1, y2, colour); draw_line(x2, y1, x2, y2, colour); } if(type != SQUARE) { draw_pixel(x1, y1, ~colour); draw_pixel(x1, y2, ~colour); draw_pixel(x2, y1, ~colour); draw_pixel(x2, y2, ~colour); } } void draw_circle(signed int xc, signed int yc, signed int radius, unsigned char fill, unsigned char colour) { signed int a = 0x0000; signed int b = 0x0000; signed int P = 0x0000; b = radius; P = (1 - b); do { if(fill != NO) { draw_line((xc - a), (yc + b), (xc + a), (yc + b), colour); draw_line((xc - a), (yc - b), (xc + a), (yc - b), colour); draw_line((xc - b), (yc + a), (xc + b), (yc + a), colour); draw_line((xc - b), (yc - a), (xc + b), (yc - a), colour); } else { draw_pixel((xc + a), (yc + b), colour); draw_pixel((xc + b), (yc + a), colour); draw_pixel((xc - a), (yc + b), colour); draw_pixel((xc - b), (yc + a), colour); draw_pixel((xc + b), (yc - a), colour); draw_pixel((xc + a), (yc - b), colour); draw_pixel((xc - a), (yc - b), colour); draw_pixel((xc - b), (yc - a), colour); } if(P < 0) { P += (3 + (2 * a++)); } else { P += (5 + (2 * ((a++) - (b--)))); } }while(a <= b); }
main.c
#include "driverlib.h" #include "delay.h" #include "SSD1306.h" #include "MAX6675.h" extern unsigned char buffer[buffer_size]; void clock_init(void); void main(void) { float t = 0; unsigned int ti = 0; WDT_A_hold(WDT_A_BASE); clock_init(); OLED_init(); MAX6675_init(); while(1) { MAX6675_get_ADC(&ti); t = MAX6675_get_T(ti, deg_C); print_float(40, 10, NUM, t, 1); delay_ms(400); }; } void clock_init(void) { PMM_setVCore(PMM_CORE_LEVEL_3); GPIO_setAsPeripheralModuleFunctionInputPin(GPIO_PORT_P5, (GPIO_PIN4 | GPIO_PIN2)); GPIO_setAsPeripheralModuleFunctionOutputPin(GPIO_PORT_P5, (GPIO_PIN5 | GPIO_PIN3)); UCS_setExternalClockSource(XT1_FREQ, XT2_FREQ); UCS_turnOnXT2(UCS_XT2_DRIVE_4MHZ_8MHZ); UCS_turnOnLFXT1(UCS_XT1_DRIVE_3, UCS_XCAP_3); UCS_initClockSignal(UCS_FLLREF, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_4); UCS_initFLLSettle(MCLK_KHZ, MCLK_FLLREF_RATIO); UCS_initClockSignal(UCS_SMCLK, UCS_XT2CLK_SELECT, UCS_CLOCK_DIVIDER_4); UCS_initClockSignal(UCS_ACLK, UCS_XT1CLK_SELECT, UCS_CLOCK_DIVIDER_1); }
Hardware Setup
Explanation
I won’t be going through hardware initialization and other common stuffs that have been covered earlier. The focus here is toward the SPI read operation.
In the MAX6675_get_ADC function, the SPI read operation can be seen.
CS_pin_low(); USCI_A_SPI_transmitData(USCI_A0_BASE, 0x00); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); hb = USCI_A_SPI_receiveData(USCI_A0_BASE); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); USCI_B_SPI_transmitData(USCI_A0_BASE, 0x00); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); lb = USCI_A_SPI_receiveData(USCI_A0_BASE); while(USCI_A_SPI_isBusy(USCI_A0_BASE)); CS_pin_high();
Although no SPI write operation is possible for MAX6675 due absence of slave-in pin in it, 0s are written prior to every SPI bus read. It is not mandatory write 0s and we can use any other value since it has no real use other than SPI clock generation. This is so because SPI bus is like a ring buffer. In SPI bus, data is simultaneously read and written with SPI clock pulses. After every complete transfer, the SPI bus is polled to check if it is free.
The demo here reads temperature with a thermocouple connected to a MAX6675 and displays the read temperature on a SSD1306 OLED display every 400 ms.
Demo
|
Hi,
Im interfacing MSP430F5529 with MAX17055 fuel guage. while reading 16 bit value, the first byte im receiving is 0. so while reading multiple registers continuously the data exchange is happening, but im getting the correct data. Can anyone suggest me what will be the issue? why im getting 0 in first byte?
read16_bit data code:
uint16_t value = 0;
USCI_B_I2C_setslaveaddress(USCI_B1_BASE, slave_address);
USCI_B_I2C_setmode(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_MODE);
USCI_B_I2C_masterSendStart(USCI_B1_BASE);
while (!USCI_B_I2C_masterSendStart(USCI_B1_BASE));
USCI_B_I2C_mastterSendSingleByte(USCI_B1_BASE, reg_address);
USCI_B_I2C_setslaveaddress(USCI_B1_BASE, slave_address);
USCI_B_I2C_setmode(USCI_B1_BASE, USCI_B_I2C_TRANSMIT_MODE);
USCI_B_I2C_masterReceiveMultiByteStart(USCI_B1_BASE);
uint8_t lb = USCI_B_I2C_masterReceiveMultiByteNext(USCI_B1_BASE);
uint8_t hb = USCI_B_I2C_masterReceiveMultiByteFinish(USCI_B1_BASE);
while (USCI_B_I2C_isBusBusy(USCI_B_BASE));
value = lb << 8;
value |= hb;
return value;
In code, after sending reg address, it will be recieve mode. its a type mistake
Hi, im trying to send the command from the terminal view. i can able to send the command and tried to blink p1.0 led in msp430f5529 controller, its working fine. And im using led driver IS31FL3236A interfaced with msp430f5529 controller, i can able to interface im getting the expected output.
now i need to send the command from seriak monitor based on that command i2c communication need to start. both communication are working fine, when it runs separately. its not working when i tried to combine.
any one had any idea, why it is happening or what will be the issue?
It could be due to:
1. conflicts in clock settings
2. hardware conflict like pin mapping
3. code is getting stuck or waiting for one communication line to finish
4. use of polling method instead of interrupt-driven coding
Hi, thank you for the respose.
Do I need to use different clock initialization for I2C and UART communication? if YES, can you explain how to do that?
I mean check which clock has been set for UART and I2C…. Is it SMCLK, MCLK, etc and is it tuned to right frequency required by the respective hardware?
Is there any example on how to implement polling method in uart?
Why go for polling method when it is a blocking method of coding? It is better to use interrupts instead at least for UART receive.
yes!! currently in my code, only for uart im using interrupts to recieve command from serial monitor. Im not using interrupt for I2C communication.
so the issue is must be in clock initialization. right?
For UART, im using USCI_A1_BASE. and for I2C, im using USCI_B1_BASE.
And another thing i need to ask is, in uart when i tried blink led(p1.0) in msp430f5529 by passing command. here, without clock I’m getting output. how it is possible?
And for both i2c and uart i gave SMCLK with 1Mhz
I am surprised and happy to find this tutorial on the F5529 as TI makes a lot of different devices.
Thank you very much for putting in the extra knowledge in each segment, made reading worthwhile.
Good Work!
lovely tutorial but to be honest I don’t think I’d be investing my time on this board to start with it’s not cheap and readily available as the stm32 boards can you please do more tutorials on stm32 board’s and the stc micros thanks
Hello, I try to program MSP430FR6047 but i get error “the debug interface to the device has been secured”. when flashing using uniflash and when program using CCS this happen. can you help me to solve this problem
You can try “On connect, erase user code and unlock the device” option.
Pingback: Tinkering TI MSP430F5529 – gStore
Hello
I am doing project of msp430g2553 interface(using i2c communication) with temp 100(temperature sensor) and try to read the temperature in dispaly(16*2) but didn’t get the out put (using code composer studio) can u share me any example code for this project
Thank you sir,
Which sensor? Did you use pullup resistors for SDA-SCL pins?
Where is lcd_print.h?
All files and docs are here:
https://libstock.mikroe.com/projects/view/3233/tinkering-ti-msp430f5529
You want the truth? TI makes and sell “underpowered micros”, you know? Low everything, not only the power but also peripherals. So the price is not justified.
Otherwise, if I’ll move there, I’ll introduce them to my small hobby projects – there are still some advantages.
I may even make a visual configuration tool of my own for them…
Yeah the prices of TI products are higher than other manufacturers but I don’t think the hardware peripherals are inferior.
Not inferior but in not enough numbers compared to STM32.
True