Advertisement
Guest User

Untitled

a guest
Apr 30th, 2022
41
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 7.78 KB | None | 0 0
  1. #include <stdint.h>
  2. #include <stdbool.h>
  3.  
  4. #include "stm32f10x.h"
  5. #include "stm32f10x_gpio.h"
  6. #include "stm32f10x_rcc.h"
  7. #include "stm32f10x_spi.h"
  8.  
  9. #include "basic_hw_init.h"
  10.  
  11. // SPI wiring configuration
  12. #define SPI_GPIO                        GPIOA
  13. #define SPI_GPIO_CLK                    RCC_APB2Periph_GPIOA
  14. #define SPI_PIN_CS                      GPIO_Pin_0
  15. #define SPI_PIN_SCLK                    GPIO_Pin_1
  16. #define SPI_PIN_MOSI                    GPIO_Pin_2
  17. #define SPI_PIN_MISO                    GPIO_Pin_3
  18. #define SPI_GPIO_SPEED                  GPIO_Speed_2MHz
  19.  
  20. // SPI for MAX7219 wiring configuration
  21.  
  22. #define MAX7219_SPI_GPIO                        GPIOB
  23. #define MAX7219_SPI_GPIO_CLK                    RCC_APB2Periph_GPIOB
  24. #define MAX7219_SPI_PIN_CS                      GPIO_Pin_13
  25. #define MAX7219_SPI_PIN_SCLK                    GPIO_Pin_14
  26. #define MAX7219_SPI_PIN_MOSI                    GPIO_Pin_12
  27. #define MAX7219_SPI_GPIO_SPEED                  GPIO_Speed_2MHz
  28.  
  29.  
  30. // For store tick counts in us
  31. volatile uint32_t usTicks;
  32.  
  33. static void setup_delay_us(void)
  34. {
  35.     // Update SystemCoreClock value
  36.     SystemCoreClockUpdate();
  37.     // Configure the SysTick timer to overflow every 1 us
  38.     SysTick_Config(SystemCoreClock / 1000000);
  39. }
  40.  
  41. static void delay_us(uint32_t us)
  42. {
  43.     // Reload us value
  44.     usTicks = us;
  45.     // Wait until usTick reach zero
  46.     while (usTicks);
  47. }
  48.  
  49. static void delay_ms(uint32_t ms)
  50. {
  51.     while (ms--)
  52.     {
  53.         // Delay 1ms
  54.         delay_us(1000);
  55.     }
  56. }
  57.  
  58. static void delay_func_spi(void)
  59. {
  60.     delay_us(1);
  61. }
  62.  
  63. static void RCC_configuration(void)
  64. {
  65.     /* PCLK2 = HCLK/2 */
  66.     RCC_PCLK2Config(RCC_HCLK_Div2);
  67.     RCC_APB2PeriphClockCmd(MAX7219_SPI_GPIO_CLK, ENABLE);
  68. }
  69.  
  70. static void GPIO_spi_configuration(void)
  71. {
  72.     GPIO_InitTypeDef GPIO_InitStructure;
  73.  
  74.     GPIO_InitStructure.GPIO_Pin = MAX7219_SPI_PIN_CS | MAX7219_SPI_PIN_SCLK | MAX7219_SPI_PIN_MOSI;
  75.     GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
  76.     GPIO_InitStructure.GPIO_Speed = MAX7219_SPI_GPIO_SPEED;
  77.     GPIO_Init(MAX7219_SPI_GPIO, &GPIO_InitStructure);
  78. }
  79.  
  80. static void spi_cs_high(void)
  81. {
  82.     GPIO_SetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_CS);
  83. }
  84.  
  85. static void spi_cs_low(void)
  86. {
  87.     GPIO_ResetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_CS);
  88. }
  89.  
  90. static void spi_send_byte(uint8_t byte)
  91. {
  92.     for(int i = 8; i > 0; --i)
  93.     {      
  94.         if(byte & (1 << (i - 1)))
  95.             GPIO_SetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_MOSI);
  96.         else
  97.             GPIO_ResetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_MOSI);
  98.         delay_func_spi();
  99.         GPIO_SetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_SCLK);
  100.         delay_func_spi();
  101.         GPIO_ResetBits(MAX7219_SPI_GPIO, MAX7219_SPI_PIN_SCLK);
  102.         delay_func_spi();
  103.     }
  104. }
  105.  
  106. static void max7219_spi_send_buffer(const uint8_t * input_buff, int len)
  107. {
  108.     uint8_t send_buf;
  109.     spi_cs_low();
  110.  
  111.     delay_func_spi();
  112.  
  113.     for(int i = 0; i < len; i++)
  114.     {
  115.         send_buf = input_buff[i];
  116.         spi_send_byte(send_buf);
  117.     }
  118.  
  119.     delay_func_spi();
  120.  
  121.     spi_cs_high();
  122. }
  123.  
  124. static void max7219_spi_init(void)
  125. {
  126.     setup_delay_us();
  127.     RCC_configuration();
  128.     GPIO_spi_configuration();
  129.     spi_cs_high();
  130.     delay_func_spi();
  131. }
  132.  
  133.  
  134.  
  135.  
  136.  
  137.  
  138.  
  139.  
  140.  
  141.  
  142.  
  143.  
  144. static void max7219_write_to_register(uint8_t addr, uint8_t data)
  145. {
  146.     uint8_t max7219_register[2];
  147.     max7219_register[0] = addr;
  148.     max7219_register[1] = data;
  149.     max7219_spi_send_buffer(max7219_register, 2);
  150. }
  151.  
  152. // Addresses for MAX7219 registers
  153. #define MAX7219_ADDR_NOOP  0x00
  154. #define MAX7219_ADDR_DIG0  0x01
  155. #define MAX7219_ADDR_DIG1  0x02
  156. #define MAX7219_ADDR_DIG2  0x03
  157. #define MAX7219_ADDR_DIG3  0x04
  158. #define MAX7219_ADDR_DIG4  0x05
  159. #define MAX7219_ADDR_DIG5  0x06
  160. #define MAX7219_ADDR_DIG6  0x07
  161. #define MAX7219_ADDR_DIG7  0x08
  162. #define MAX7219_ADDR_MODE  0x09
  163. #define MAX7219_ADDR_INT   0x0A
  164. #define MAX7219_ADDR_LIM   0x0B
  165. #define MAX7219_ADDR_SHUT  0x0C
  166. #define MAX7219_ADDR_TEST  0x0F
  167.  
  168.  
  169. static void max7219_enable_display(void)
  170. {
  171.     max7219_write_to_register(MAX7219_ADDR_SHUT, 0x01U);
  172. }
  173.  
  174. static void max7219_test_display(void)
  175. {
  176.     max7219_write_to_register(MAX7219_ADDR_TEST, 0x01U);
  177.     delay_ms(1000);
  178.     max7219_write_to_register(MAX7219_ADDR_TEST, 0x00U);
  179.     delay_ms(1000);
  180. }
  181.  
  182. static uint8_t hex_2_sevensegment[16] = {  0x7e, // 0
  183.                                            0x30, // 1
  184.                                            0x6d, // 2
  185.                                            0x79, // 3
  186.                                            0x33, // 4
  187.                                            0x5b, // 5
  188.                                            0x5f, // 6
  189.                                            0x70, // 7
  190.                                            0x7f, // 8
  191.                                            0x7b, // 9
  192.                                            0x77, // A
  193.                                            0x1f, // b
  194.                                            0x4e, // C
  195.                                            0x3d, // d
  196.                                            0x6f, // e
  197.                                            0x47  // f
  198.                                            };
  199. #define MAX7219_DIGIT_POINT  0x80U
  200. #define MAX7219_DIGIT_MINUS  0x01U
  201.  
  202. static void max7219_display_overflow(void)
  203. {
  204.     for(int i = 1; i < 9; i++) // Offset to map on addresses of MAX7219
  205.     {
  206.         max7219_write_to_register(i, MAX7219_DIGIT_MINUS);
  207.     }
  208. }
  209.  
  210. void max7219_set_hex(uint32_t val)
  211. {
  212.     uint8_t nibble;
  213.     uint8_t segments_to_activate;
  214.     for(int i = 1; i < 9; i += 2) // Offset to map on addresses of MAX7219
  215.     {
  216.         nibble = val & 0x0FU;
  217.         segments_to_activate = hex_2_sevensegment[nibble];
  218.         if(val)
  219.             max7219_write_to_register(i, segments_to_activate);
  220.         else
  221.             max7219_write_to_register(i, 0x00U); // Blank leading zeroes
  222.         val >>= 4;
  223.  
  224.         nibble = val & 0x0FU;
  225.         segments_to_activate = hex_2_sevensegment[nibble];
  226.         if(val)
  227.             max7219_write_to_register(i + 1, segments_to_activate);
  228.         else
  229.             max7219_write_to_register(i + 1, 0x00U); // Blank leading zeroes
  230.         val >>= 4;
  231.     }
  232. }
  233.  
  234.  
  235. // Displays -9999999 ... 99999999 with point
  236. void max7219_set_dec(int32_t val, uint8_t point_pos)
  237. {
  238.     bool has_minus = false;
  239.     uint8_t segments_to_activate;
  240.     uint8_t digit;
  241.  
  242.     // Check for usable bounds
  243.     if(val < -9999999)
  244.     {
  245.         max7219_display_overflow();
  246.         return;
  247.     }
  248.     if(val > 99999999)
  249.     {
  250.         max7219_display_overflow();
  251.         return;
  252.     }
  253.  
  254.     // Check for minus sign
  255.    
  256.     if(val < 0)
  257.     {
  258.         val = -val;
  259.         has_minus = true;
  260.     }
  261.  
  262.     // Write decimal digits
  263.     for(int i = 1; i < 9; i++) // Offset to map on addresses of MAX7219
  264.     {
  265.         digit = val % 10u;
  266.         segments_to_activate = hex_2_sevensegment[digit];
  267.         if(point_pos == (i - 1)) segments_to_activate |= MAX7219_DIGIT_POINT;
  268.  
  269.         if(val || (point_pos + 2 > i))
  270.             max7219_write_to_register(i, segments_to_activate);
  271.         else // Blank leading zeroes
  272.         {
  273.             if(has_minus) // Put minus to the first unused position
  274.             {
  275.                 has_minus = false;
  276.                 max7219_write_to_register(i, MAX7219_DIGIT_MINUS);
  277.             }
  278.             else
  279.                 max7219_write_to_register(i, 0x00U);
  280.         }
  281.         val /= 10;
  282.     }
  283.  
  284. }
  285.  
  286.  
  287. void max7219_init(void)
  288. {
  289.     max7219_spi_init();
  290.     max7219_enable_display();
  291.     max7219_test_display();
  292.  
  293.    
  294.     max7219_write_to_register(MAX7219_ADDR_MODE, 0x00U);
  295.     max7219_write_to_register(MAX7219_ADDR_LIM,  0x07U);
  296.     max7219_write_to_register(MAX7219_ADDR_INT,  0x06U); // Intensity of display
  297.     max7219_set_hex(0);
  298. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement