Advertisement
Guest User

Untitled

a guest
Dec 17th, 2017
93
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C 13.67 KB | None | 0 0
  1.  
  2. #include <stdio.h>
  3. #include <stdlib.h>
  4. #include <string.h>
  5. #include "stm32f401_discovery.h"
  6. #include "stm32f401_discovery_audio.h"
  7. #include "main.h"
  8.  
  9.  
  10. char get_lcd_embd_h(char);
  11. char get_lcd_embd_l(char);
  12. void send_char_to_lcd(char);
  13. UART_HandleTypeDef EspInit(void);
  14. void clear_lcd();
  15. void cursor_to_home();
  16. void init_lcd();
  17.  
  18. I2C_HandleTypeDef hi2c1;
  19.  
  20. UART_HandleTypeDef esp;
  21.  
  22. #define LCD_ADD         0x27 // Адрес LCD на шине I2C
  23. #define LCD_ADD_W   0x7E // Адрес LCD на шине I2C для записи
  24. #define LCD_ADD_R   0x7F // Адрес LCD на шине I2C для чтения
  25.  
  26.  
  27. char ans[25] = {0};
  28.  
  29.  
  30. // ----- main() ---------------------------------------------------------------
  31. // Точка входа в программу
  32. int
  33. main(int argc, char* argv[])
  34. {
  35.  
  36.     HAL_Init(); // инициализация библиотеки HAL
  37.     SystemClock_Config(); // настройка таймера (необходимо для задания задержек)
  38.     // инициализация входов/выходов общего назначения для передачи на дисплей по I2C    
  39.     MX_GPIO_Init();
  40.     I2c_Init(&hi2c1); // настройка передачи по I2C
  41.     init_lcd(); // инициализация дисплея
  42.     esp = EspInit(); // инициалзация wifi модуля (приемник)
  43.  
  44.     // настройка wifi модуля
  45.     // AT+CWMODE=3 - режим модуля Station (server) и AP
  46.     HAL_UART_Transmit(&esp, "AT+CWMODE=3\r\n", strlen("AT+CWMODE=3\r\n"), 5000);
  47.         HAL_Delay(50); // для нормальной инициализации нужна небольшая задержка
  48.     send_char_to_lcd('c');
  49.     // AT+CIPMODE=1 - обычный режим пережачи
  50.     HAL_UART_Transmit(&esp, "AT+CIPMODE=0\r\n", strlen("AT+CIPMODE=0\r\n"), 5000);
  51.     cursor_to_home();
  52.     // AT+CIPMUX=1 - поддерживание множественного подключения к сети
  53.     HAL_UART_Transmit(&esp, "AT+CIPMUX=1\r\n", strlen("AT+CIPMUX=1\r\n"), 5000);
  54.     cursor_to_home();
  55.     send_char_to_lcd('c');
  56.     // AT+CIPSERVER=1,88 - стартуем TCP сервер на 88 порту (по нему и будем стучаться)
  57.     HAL_UART_Transmit(&esp, "AT+CIPSERVER=1,88\r\n", strlen("AT+CIPSERVER=1,88\r\n"), 5000);
  58.     cursor_to_home();
  59.     send_char_to_lcd('s');
  60.     // инициализируем прерывания по приему на UART
  61.     HAL_UART_Receive_IT(&esp, ans, 1);
  62.     __HAL_UART_ENABLE_IT(&esp, UART_IT_RXNE);
  63.     while(1){
  64.         // Ждем когда будем выставлен флаг SET (прием каких-то данных по UART)
  65.             if(UartReady == SET){
  66.             // проверяем, была ли в принят. данных искомая посл-ть
  67.                 if(strstr(ans, "+IPD:0,")){
  68.                 cursor_to_home();
  69.                     for(int i = 12; i < 25; i++)
  70.                             send_char_to_lcd(ans[i]);
  71.                         send_char_to_lcd(' ');
  72.                 }
  73.                 memset(ans, 0, 25);
  74.                 UartReady = RESET;
  75.                 HAL_UART_Receive_IT(&esp, ans, 1);
  76.             }  
  77.         }
  78.  
  79.  }
  80.  
  81.  
  82. // ----- EspInit() ---------------------------------------------------------------
  83. // Инициализация wi-fi модуля приемника
  84. UART_HandleTypeDef EspInit(void){
  85.     // инициализируем тактирование шины портов
  86.     __HAL_RCC_USART2_CLK_ENABLE();
  87.     __HAL_RCC_GPIOA_CLK_ENABLE();
  88.  
  89.     GPIO_InitTypeDef GPIO_InitStruct;
  90.  
  91.     GPIO_InitStruct.Pin = GPIO_PIN_2|GPIO_PIN_3; // выбираем 2 и 3 порты (PA2, PA3)
  92.     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; // выбираем альтернативную функцию (UART)
  93.     GPIO_InitStruct.Pull = GPIO_PULLUP; // подтягиваем к питанию выводы (необходимо для норм. работы(см. дз. 2))
  94.     GPIO_InitStruct.Speed = GPIO_SPEED_HIGH; // задаем скорость работы
  95.     GPIO_InitStruct.Alternate = GPIO_AF7_USART2; // выбираем UART2
  96.     HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
  97.  
  98.     UART_HandleTypeDef huart1;
  99.  
  100.     huart1.Instance = USART2; // работаем с UART2
  101.     huart1.Init.BaudRate = 115200; // выбираем 115200 бод (см. значения в дз)
  102.     huart1.Init.WordLength = UART_WORDLENGTH_8B; // задаем длину слова
  103.     huart1.Init.StopBits = UART_STOPBITS_1; // задаем один стоп бит
  104.     huart1.Init.Parity = UART_PARITY_NONE; // задаем, что не будет бита четности
  105.     huart1.Init.Mode = UART_MODE_TX_RX; // режим прием/передача
  106.     huart1.Init.HwFlowCtl = UART_HWCONTROL_NONE;
  107.     huart1.Init.OverSampling = UART_OVERSAMPLING_16;
  108.  
  109.     HAL_NVIC_SetPriority(USART2_IRQn, 0, 0); // задаем приоритет прерываний для UART (наивысший)
  110.     HAL_NVIC_EnableIRQ(USART2_IRQn);
  111.  
  112.     return huart1;
  113. }
  114.  
  115. // ----- get_lcd_embd_h(char) ---------------------------------------------------------------
  116. /*
  117.     Получение четырех старших битов для отправки. Кодирование данных
  118.     проиводим в соответсв. с таблицей кодирования из
  119.     документации на LCD
  120. */
  121. char get_lcd_embd_h(char a){
  122.     switch (a) {
  123.     case '0' ... '9':
  124.         return 0b0011;
  125.     case 'A' ... 'O':
  126.         return 0b0100;
  127.     case 'P' ... 'Z':
  128.         return 0b0101;
  129.     case 'a' ... 'o':
  130.         return 0b0110;
  131.     case 'p' ... 'z':
  132.         return 0b0111;
  133.     case '.':
  134.         return 0b0010;
  135.     case ' ':
  136.             return 0b0001;
  137.     default:
  138.         return 0b1101;
  139.     }
  140. }
  141.  
  142. // ----- get_lcd_embd_l(char) ---------------------------------------------------------------
  143. /*
  144.     Получение четырех младших битов для отправки. Кодирование данных
  145.     проиводим в соответсв. с таблицей кодирования из
  146.     документации на LCD
  147. */
  148. char get_lcd_embd_l(char a){
  149.     switch(a){
  150.     case '0' ... '9':
  151.         return a-'0';
  152.     case 'A' ... 'O':
  153.         return a -'A' + 1;
  154.     case 'P' ... 'Z':
  155.         return a-'P';
  156.     case 'a' ... 'o':
  157.         return a -'a' + 1;
  158.     case 'p' ... 'z':
  159.         return a-'p';
  160.     case '.':
  161.         return 0b1110;
  162.     case ' ':
  163.         return 0b0000;
  164.     default:
  165.         return 0b1111;
  166.     }
  167. }
  168.  
  169.  
  170. // ----- send_char_to_lcd(char) ---------------------------------------------------------------
  171. /*
  172.     Отправка полноценного пакета с данными.
  173.     Т.к. в нашей схеме придусмотрен расширитель портов, поэтому
  174.     необходимо задать режим передачи по 4 бита, а затем
  175.     слать стачала 4 старших, за котороми 4 младших бита.
  176.     Формирование битов производим в соотв. с таблицей
  177.     кодирования данных из документации на LCD.
  178. */
  179. void send_char_to_lcd(char to_send){
  180.     char h_part = (get_lcd_embd_h(to_send) << 4) + 0b1101;
  181.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, &h_part, 1, 0x100);
  182.     char l_part = (get_lcd_embd_l(to_send) << 4) + 0b1101;
  183.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, &l_part, 1, 0x100);
  184. }
  185.  
  186.  
  187. // ----- clear_lcd(char) ---------------------------------------------------------------
  188. /*
  189.     Фун-ия для очистки экрана.
  190.     По док-ии команда для очистки имеет вид 00000001
  191.     Т.к. мы шлем по 4 бита, поэтому разбеляем всю последовательность
  192.     на две части: сначала шлем старшие, а за ними младшие.
  193.     Остальные 4 бита (1100) задают режим работы LCD (выключать ли подскетку и т.д.)
  194.     Подробнее см. отчет.
  195. */
  196. void clear_lcd(){
  197.     char cmd = 0b00001100;
  198.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, &cmd, 1, 0x100);
  199.     HAL_Delay(10);
  200.     cmd = 0b00011100;
  201.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, &cmd, 1, 0x100);
  202.     HAL_Delay(10);
  203. }
  204.  
  205.  
  206. // ----- cursor_to_home() ---------------------------------------------------------------
  207. /*
  208.     Фун-ия для перевода курсора в начало экрана.
  209.     По док-ии команда для очистки имеет вид 0000001x (x - don't care value)
  210.     Т.к. мы шлем по 4 бита, поэтому разбеляем всю последовательность
  211.     на две части: сначала шлем старшие, а за ними младшие.
  212.     Остальные 4 бита (1100) задают режим работы LCD (выключать ли подскетку и т.д.)
  213.     Подробнее см. отчет.
  214. */
  215. void cursor_to_home(){
  216.     char cmd = 0b00001100;
  217.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, &cmd, 1, 0x100);
  218.     HAL_Delay(10);
  219.     cmd = 0b00101100;
  220.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, &cmd, 1, 0x100);
  221.     HAL_Delay(10);
  222. }
  223.  
  224.  
  225. // ----- init_lcd() ---------------------------------------------------------------
  226. /*
  227.     Инициализация LCD.
  228.     Для задания корректной работы LCD предумотрен ряд команд
  229.     в документации, которые очищают экран, явно задают режим (в нашем случае -
  230.     передача по 4 бита) и т.д. (подробнее см. документацию на LCD1602A)
  231.     Передачу производим посредством протокола I2C, по которому работает
  232.     расширитель портов, который припаян к LCD.
  233. */
  234. void init_lcd(){
  235.     HAL_Delay(50);
  236.     uint8_t cmd[1];
  237.     cmd[0] = 0b00111100;
  238.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  239.     HAL_Delay(6);
  240.     cmd[0] = 0b00111100;
  241.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  242.     HAL_Delay(1);
  243.     cmd[0] = 0b00111100;
  244.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  245.     cmd[0] = 0b00101100;
  246.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  247.     cmd[0] = 0b00101100;
  248.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  249.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  250.     cmd[0] = 0b00001100;
  251.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  252.     cmd[0] = 0b10001100;
  253.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  254.     cmd[0] = 0b00001100;
  255.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  256.     cmd[0] = 0b00011100;
  257.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  258.     cmd[0] = 0b00001100;
  259.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  260.     cmd[0] = 0b01101100;
  261.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  262.     cmd[0] = 0b00001100;
  263.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  264.     cmd[0] = 0b11111100;
  265.     HAL_I2C_Mem_Write(&hi2c1, LCD_ADD_W, 0x00, 1, cmd, 1, 0x100);
  266. }
  267.  
  268. // ----- HAL_UART_RxCpltCallback(UART_HandleTypeDef*) ---------------------------------------------------------------
  269. /*
  270.     Обработчки прерывания приема данных на LCD.
  271. */
  272. void HAL_UART_RxCpltCallback(UART_HandleTypeDef *UartHandle)
  273. {
  274.     UartReady = SET;
  275.     if (ans[0]){
  276.         if (HAL_UART_Receive(&esp, ans, 25, 1) != HAL_OK){
  277.             HAL_UART_Receive_IT(&esp, ans, 1); // явно задаем прием на 1 байт
  278.         }
  279.     }
  280. }
  281.  
  282. // ----- MX_GPIO_Init() ---------------------------------------------------------------
  283. /*
  284.     Задание выводов общего назначение для работы
  285.     по протоколу I2C.
  286. */
  287. static void MX_GPIO_Init(void){
  288.  
  289.     /**I2C1 GPIO Configuration
  290.      PB6     ------> I2C1_SCL
  291.      PB7     ------> I2C1_SDA
  292.      */
  293.     __HAL_RCC_I2C1_CLK_ENABLE();
  294.     __HAL_RCC_GPIOB_CLK_ENABLE();
  295.     GPIO_InitTypeDef GPIO_InitStruct;
  296.     GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
  297.     // Задаем режим альтеративной функции. Для протокола I2C это должен быть OP (Open Drain/Открытый коллектор)
  298.     GPIO_InitStruct.Mode = GPIO_MODE_AF_OD;
  299.     GPIO_InitStruct.Pull = GPIO_PULLUP; // Подтягиваем вывода к питанию
  300.     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; // Задаем частоту работы
  301.     GPIO_InitStruct.Alternate = GPIO_AF4_I2C1; // Выбираем альтернативную фун-ию как работу по I2C1
  302.     HAL_GPIO_Init(GPIOB, &GPIO_InitStruct); // Инициализируем выбранные выше параметры
  303.       __HAL_RCC_I2C1_CLK_ENABLE();
  304.     /* Задаем тактирование шины портов */
  305.     __HAL_RCC_GPIOC_CLK_ENABLE();
  306.     __HAL_RCC_GPIOH_CLK_ENABLE();
  307.     __HAL_RCC_GPIOB_CLK_ENABLE();
  308. }
  309.  
  310.  
  311. // ----- I2c_Init() ---------------------------------------------------------------
  312. /*
  313.     Инициализация для работы I2C.
  314. */
  315. I2C_HandleTypeDef I2c_Init(void){
  316.     __HAL_RCC_I2C1_CLK_ENABLE();
  317.     __HAL_RCC_GPIOB_CLK_ENABLE();
  318.  
  319.     GPIO_InitTypeDef gpio;
  320.     I2C_HandleTypeDef i2c;
  321.  
  322.     i2c.Instance = I2C1;
  323.     i2c.Init.ClockSpeed = 100000;
  324.     i2c.Init.DutyCycle = I2C_DUTYCYCLE_2;
  325.     i2c.Init.OwnAddress1 = 0x15;
  326.     i2c.Init.AddressingMode = I2C_ADDRESSINGMODE_7BIT;
  327.     i2c.Init.DualAddressMode = I2C_DUALADDRESS_DISABLE;
  328.     i2c.Init.OwnAddress2 = 0x00;
  329.     i2c.Init.GeneralCallMode = I2C_GENERALCALL_DISABLE;
  330.     i2c.Init.NoStretchMode = I2C_NOSTRETCH_DISABLE;
  331.  
  332.     gpio.Pin = GPIO_PIN_9 | GPIO_PIN_6;
  333.     gpio.Mode = GPIO_MODE_AF_OD;
  334.     gpio.Pull = GPIO_NOPULL;
  335.     gpio.Speed = GPIO_SPEED_FREQ_HIGH;
  336.     gpio.Alternate = GPIO_AF4_I2C1;
  337.  
  338.     HAL_GPIO_Init(GPIOB, &gpio);
  339.  
  340.     __HAL_RCC_I2C1_FORCE_RESET();
  341.     __HAL_RCC_I2C1_RELEASE_RESET();
  342.  
  343.     HAL_I2C_Init(&i2c);
  344.  
  345.     uint8_t ctrl_reg_byte = 0xE0;
  346.  
  347.     return i2c;
  348. }
  349. #pragma GCC diagnostic pop
  350.  
  351. // ----------------------------------------------------------------------------
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement