Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdint.h>
- #include <stdbool.h>
- #include "stm32f10x.h"
- #include "stm32f10x_gpio.h"
- #include "stm32f10x_rcc.h"
- #include "stm32f10x_spi.h"
- #include "basic_hw_init.h"
- // SPI wiring configuration
- #define SPI_GPIO GPIOA
- #define SPI_GPIO_CLK RCC_APB2Periph_GPIOA
- #define SPI_PIN_CS GPIO_Pin_0
- #define SPI_PIN_SCLK GPIO_Pin_1
- #define SPI_PIN_MOSI GPIO_Pin_2
- #define SPI_PIN_MISO GPIO_Pin_3
- #define SPI_GPIO_SPEED GPIO_Speed_2MHz
- // SPI for MAX7219 wiring configuration
- #define MAX7219_SPI_GPIO GPIOB
- #define MAX7219_SPI_GPIO_CLK RCC_APB2Periph_GPIOB
- #define MAX7219_SPI_PIN_CS GPIO_Pin_13
- #define MAX7219_SPI_PIN_SCLK GPIO_Pin_14
- #define MAX7219_SPI_PIN_MOSI GPIO_Pin_12
- #define MAX7219_SPI_GPIO_SPEED GPIO_Speed_2MHz
- // For store tick counts in us
- volatile uint32_t usTicks;
- static void setup_delay_us(void)
- {
- // Update SystemCoreClock value
- SystemCoreClockUpdate();
- // Configure the SysTick timer to overflow every 1 us
- SysTick_Config(SystemCoreClock / 1000000);
- }
- static void delay_us(uint32_t us)
- {
- // Reload us value
- usTicks = us;
- // Wait until usTick reach zero
- while (usTicks);
- }
- static void delay_ms(uint32_t ms)
- {
- while (ms--)
- {
- // Delay 1ms
- delay_us(1000);
- }
- }
- static void delay_func_spi(void)
- {
- delay_us(1);
- }
- static void RCC_configuration(void)
- {
- /* PCLK2 = HCLK/2 */
- RCC_PCLK2Config(RCC_HCLK_Div2);
- RCC_APB2PeriphClockCmd(MAX7219_SPI_GPIO_CLK, ENABLE);
- }
- static void GPIO_spi_configuration(void)
- {
- GPIO_InitTypeDef GPIO_InitStructure;
- GPIO_InitStructure.GPIO_Pin = MAX7219_SPI_PIN_CS | MAX7219_SPI_PIN_SCLK | MAX7219_SPI_PIN_MOSI;
- GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
- GPIO_InitStructure.GPIO_Speed = MAX7219_SPI_GPIO_SPEED;
- GPIO_Init(MAX7219_SPI_GPIO, &GPIO_InitStructure);
- }
- static void spi_cs_high(void)
- {
- GPIO_SetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_CS);
- }
- static void spi_cs_low(void)
- {
- GPIO_ResetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_CS);
- }
- static void spi_send_byte(uint8_t byte)
- {
- for(int i = 8; i > 0; --i)
- {
- if(byte & (1 << (i - 1)))
- GPIO_SetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_MOSI);
- else
- GPIO_ResetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_MOSI);
- delay_func_spi();
- GPIO_SetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_SCLK);
- delay_func_spi();
- GPIO_ResetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_SCLK);
- delay_func_spi();
- }
- }
- static void max7219_spi_send_buffer(const uint8_t * input_buff, int len)
- {
- uint8_t send_buf;
- spi_cs_low();
- delay_func_spi();
- for(int i = 0; i < len; i++)
- {
- send_buf = input_buff[i];
- spi_send_byte(send_buf);
- }
- delay_func_spi();
- spi_cs_high();
- }
- static void max7219_spi_init(void)
- {
- setup_delay_us();
- RCC_configuration();
- GPIO_spi_configuration();
- spi_cs_high();
- delay_func_spi();
- }
- static void max7219_write_to_register(uint8_t addr, uint8_t data)
- {
- uint8_t max7219_register[2];
- max7219_register[0] = addr;
- max7219_register[1] = data;
- max7219_spi_send_buffer(max7219_register, 2);
- }
- // Addresses for MAX7219 registers
- #define MAX7219_ADDR_NOOP 0x00
- #define MAX7219_ADDR_DIG0 0x01
- #define MAX7219_ADDR_DIG1 0x02
- #define MAX7219_ADDR_DIG2 0x03
- #define MAX7219_ADDR_DIG3 0x04
- #define MAX7219_ADDR_DIG4 0x05
- #define MAX7219_ADDR_DIG5 0x06
- #define MAX7219_ADDR_DIG6 0x07
- #define MAX7219_ADDR_DIG7 0x08
- #define MAX7219_ADDR_MODE 0x09
- #define MAX7219_ADDR_INT 0x0A
- #define MAX7219_ADDR_LIM 0x0B
- #define MAX7219_ADDR_SHUT 0x0C
- #define MAX7219_ADDR_TEST 0x0F
- static void max7219_enable_display(void)
- {
- max7219_write_to_register(MAX7219_ADDR_SHUT, 0x01U);
- }
- static void max7219_test_display(void)
- {
- max7219_write_to_register(MAX7219_ADDR_TEST, 0x01U);
- delay_ms(1000);
- max7219_write_to_register(MAX7219_ADDR_TEST, 0x00U);
- delay_ms(1000);
- }
- static uint8_t hex_2_sevensegment[16] = { 0x7e, // 0
- 0x30, // 1
- 0x6d, // 2
- 0x79, // 3
- 0x33, // 4
- 0x5b, // 5
- 0x5f, // 6
- 0x70, // 7
- 0x7f, // 8
- 0x7b, // 9
- 0x77, // A
- 0x1f, // b
- 0x4e, // C
- 0x3d, // d
- 0x6f, // e
- 0x47 // f
- };
- #define MAX7219_DIGIT_POINT 0x80U
- #define MAX7219_DIGIT_MINUS 0x01U
- static void max7219_display_overflow(void)
- {
- for(int i = 1; i < 9; i++) // Offset to map on addresses of MAX7219
- {
- max7219_write_to_register(i, MAX7219_DIGIT_MINUS);
- }
- }
- void max7219_set_hex(uint32_t val)
- {
- uint8_t nibble;
- uint8_t segments_to_activate;
- for(int i = 1; i < 9; i += 2) // Offset to map on addresses of MAX7219
- {
- nibble = val & 0x0FU;
- segments_to_activate = hex_2_sevensegment[nibble];
- if(val)
- max7219_write_to_register(i, segments_to_activate);
- else
- max7219_write_to_register(i, 0x00U); // Blank leading zeroes
- val >>= 4;
- nibble = val & 0x0FU;
- segments_to_activate = hex_2_sevensegment[nibble];
- if(val)
- max7219_write_to_register(i + 1, segments_to_activate);
- else
- max7219_write_to_register(i + 1, 0x00U); // Blank leading zeroes
- val >>= 4;
- }
- }
- // Displays -9999999 ... 99999999 with point
- void max7219_set_dec(int32_t val, uint8_t point_pos)
- {
- bool has_minus = false;
- uint8_t segments_to_activate;
- uint8_t digit;
- // Check for usable bounds
- if(val < -9999999)
- {
- max7219_display_overflow();
- return;
- }
- if(val > 99999999)
- {
- max7219_display_overflow();
- return;
- }
- // Check for minus sign
- if(val < 0)
- {
- val = -val;
- has_minus = true;
- }
- // Write decimal digits
- for(int i = 1; i < 9; i++) // Offset to map on addresses of MAX7219
- {
- digit = val % 10u;
- segments_to_activate = hex_2_sevensegment[digit];
- if(point_pos == (i - 1)) segments_to_activate |= MAX7219_DIGIT_POINT;
- if(val || (point_pos + 2 > i))
- max7219_write_to_register(i, segments_to_activate);
- else // Blank leading zeroes
- {
- if(has_minus) // Put minus to the first unused position
- {
- has_minus = false;
- max7219_write_to_register(i, MAX7219_DIGIT_MINUS);
- }
- else
- max7219_write_to_register(i, 0x00U);
- }
- val /= 10;
- }
- }
- void max7219_init(void)
- {
- max7219_spi_init();
- max7219_enable_display();
- max7219_test_display();
- max7219_write_to_register(MAX7219_ADDR_MODE, 0x00U);
- max7219_write_to_register(MAX7219_ADDR_LIM, 0x07U);
- max7219_write_to_register(MAX7219_ADDR_INT, 0x06U); // Intensity of display
- max7219_set_hex(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement