Advertisement
Guest User

exp8b

a guest
Oct 20th, 2016
117
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 33.06 KB | None | 0 0
  1.  
  2. /*!
  3. * \file main.c
  4. * \brief Renderização dos caracteres ASCII em LCD
  5. *
  6. * \details Este código ilustra a inicialização e a transferência de dados entre
  7. * um LCD e o MKZ25Z128 através de uma interface paralela.
  8. * \mainpage Projeto de identificação de intervalo de tempo em que se mantém um push-button pressionado.
  9. * \author Wu Shin-Ting edited by Lucas Perissinotto 158149
  10. * \date 20/10/2016
  11. * \note Documentação do código no formato de Doxygen:
  12. * http://mcuoneclipse.com/2014/09/01/automatic-documentation-generation-doxygen-with-processor-expert/
  13. */
  14.  
  15. #include "derivative.h" ///< include peripheral declarations
  16. #include "stdlib.h" ///< include peripheral declarations
  17. #include "string.h" ///< include memory operation functions
  18.  
  19. /*
  20. * Enumera&ccedil&atilde;o das cores do led
  21. */
  22. typedef enum _tipo_led {
  23. VERMELHO, /*!< vermelho */
  24. VERDE, /*!< verde */
  25. AZUL /*! azul */
  26. } tipo_led;
  27.  
  28. /*
  29. * Enumera&ccedil&atilde;o dos estados do led
  30. */
  31. typedef enum _estado_led {
  32. ACESO, /*!< aceso */
  33. APAGADO /*!< apagado */
  34. } estado_led;
  35.  
  36. /*
  37. * Enumera&ccedil&atilde;o da botoeira
  38. */
  39. typedef enum _tipo_pta {
  40. PTA5, /*!< pino 5 da porta A */
  41. PTA12 /*!< pino 12 da porta A */
  42. } tipo_pta;
  43.  
  44. /*
  45. * Enumera&ccedil&atilde;o do sinal de Enable
  46. */
  47. typedef enum _tipo_enable {
  48. LCD, /*!< sinal Enable do LCD */
  49. LEDS /*!< sinal Enable dos Leds */
  50. } tipo_enable;
  51.  
  52. /*
  53. * Estrutura para representar uma cor pelos estados dos 3 leds
  54. */
  55. typedef struct _cor {
  56. enum _estado_led vermelho; /*!< estado do led vermelho */
  57. enum _estado_led verde; /*!< estado do led verde */
  58. enum _estado_led azul; /*!< estado do led azul */
  59. } cor;
  60.  
  61. typedef enum _tipo_buffer {
  62. RECEPTOR,
  63. TRANSMISSOR
  64. } tipo_buffer;
  65.  
  66. #define MAX 488
  67.  
  68. struct _buffer_uart {
  69. short head_receptor;
  70. short tail_receptor;
  71. char receptor[MAX];
  72. short head_transmissor;
  73. short tail_transmissor;
  74. //char transmissor[4880];
  75. char transmissor[MAX];
  76. } buffer_uart;
  77.  
  78. void initUART(void) {
  79. /*!
  80. * Configura&ccedil;&atilde;o de SIM
  81. */
  82. SIM_CLKDIV1 &= (uint32_t)~(uint32_t)(SIM_CLKDIV1_OUTDIV4(0x7)); ////< bus_clock = clock/1
  83. SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
  84. SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
  85. SIM_SOPT2 |= SIM_SOPT2_UART0SRC(0x1); ///< configura a fonte de relógio (20.971520MHz)
  86. SIM_SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
  87. ///< no reset, o valor é zero (FLL)
  88. ///< mas não deixa de ser uma boa
  89. ///< prática de inicializar explicitamente
  90.  
  91. /*!
  92. * Configura&ccedil;&atilde;o dos pinos que servem UART0
  93. */
  94. PORTA_PCR1 |= PORT_PCR_MUX(0x2); ///< UART0_RX
  95. PORTA_PCR2 |= PORT_PCR_MUX(0x2); ///< UART0_TX
  96.  
  97. /*!
  98. * Configura&ccedil;&atilde;o do m&oacute;dulo UART0
  99. */
  100. UART0_C1 &= ~(UART0_C1_PE_MASK | // a) Configure "no paridade"
  101. UART0_C1_ILT_MASK |
  102. UART0_C1_WAKE_MASK | // b) Configure "idle-line wakep" na recepcao
  103. UART0_C1_M_MASK | // Configure "dados de 8 bits"
  104. UART0_C1_DOZEEN_MASK |
  105. UART0_C1_LOOPS_MASK );
  106. UART0_C2 &= ~(UART_C2_RE_MASK | // c) Por quê desabilita os dois canais:
  107. // receptor e transmissor?
  108. UART_C2_TE_MASK);
  109. UART0_BDH &= ~(UART_BDH_SBNS_MASK | // d) Configure "1 stop bits"
  110. UART_BDH_RXEDGIE_MASK |
  111. UART_BDH_LBKDIE_MASK);
  112. UART0_C4 |= UART0_C4_OSR(0xF); // e) Configure "taxa de amostragem 16".
  113. // Compare com a forma de configuracao no
  114. // programa "exp6_polling.c" e justifique
  115. // a diferenca.
  116. /*!
  117. * baud rate 19200 (Se&ccedil;&atilde;o 8.3.2 em
  118. * ftp://ftp.dca.fee.unicamp.br/pub/docs/ea871/ARM/KLQRUG.pdf)
  119. */
  120. UART0_BDH |= UART_BDH_SBR(0x00);
  121. UART0_BDL |= UART_BDL_SBR(0x44); ///< f) Configure baud rate 19200
  122.  
  123. UART0_S1 |= (UART0_S1_PF_MASK | ///< Registradores de estado: w1c
  124. UART0_S1_FE_MASK |
  125. UART0_S1_NF_MASK |
  126. UART0_S1_OR_MASK |
  127. UART0_S1_IDLE_MASK);
  128.  
  129. UART0_C2 |= (UART_C2_RIE_MASK | ///< ativa interrup&ccedil;&atilde;o de recep&ccedil&atilde;o
  130. UART_C2_RE_MASK | ///< habilita o canal receptor
  131. UART_C2_TE_MASK); ///< habilita o canal transmissor
  132. ///< g) por que nao e ativada a interrupcao do transmissor?
  133.  
  134. // h) No programa "exp6_polling.c" setamos um campo do registrador UARTx_C5. Por que
  135. // neste programa nao?
  136. }
  137.  
  138. /*
  139. * Estrutura para representar a instru??o do LCD e o seu tempo de processamento
  140. */
  141. typedef struct _lcd {
  142. uint8_t cop;
  143. uint8_t tempo;
  144. } lcd;
  145.  
  146. #define GPIO_PIN(x) ((1)<<(x)) ///< obtem o bit do pino x
  147. #define LCD_FUNCTION_SET 0x38
  148. #define LCD_DISPLAY_CONTROL 0x0C
  149. #define LCD_DISPLAY_CLEAR 0x01
  150. #define LCD_ENTRY_MODE_SET 0x06
  151.  
  152. unsigned int tempo, tempo5, tempo12; ///< m&uacute;ltiplo de 10us
  153. uint8_t estado_pta5, estado_pta12;
  154. uint8_t indice5 = 5, indice12 = 5;
  155. float temp;
  156. /*! Declara??o dos nomes das cores */
  157. //Ting: inserir espacos para evitar "limpa"
  158. /*
  159. char vermelho[] = "VERMELHO";
  160. char branco[] = "BRANCO";
  161. char amarelo[] = "AMARELO";
  162. char ciano[] = "CIANO";
  163. char magenta[] = "MAGENTA";
  164. char preto[] = "PRETO";
  165. */
  166.  
  167. char vermelho[] = "VERMELHO";
  168. char branco[] = "BRANCO ";
  169. char amarelo[] = "AMARELO ";
  170. char ciano[] = "CIANO ";
  171. char magenta[] = "MAGENTA ";
  172. char preto[] = "PRETO ";
  173.  
  174. // Ting: verde
  175. char verde[] = "VERDE ";
  176.  
  177. void delay10us (unsigned int t)
  178. {
  179. tempo = 0;
  180. while (tempo < t) {}
  181. }
  182.  
  183. /*!
  184. * \fn ConvUIpraDec(unsigned int j, char * s)
  185. * \brief Converte em ASCII o inteiro sem sinal j.
  186. * \param[in] j valor inteiro sem sinal
  187. * \param[out] s representa&ccedil;&atilde;o em ASCII
  188. */
  189. void ConvUIpraDec (unsigned int j, char * s) {
  190. short k = 0;
  191. char aux[11];
  192. /*!
  193. * Passo 1: extrai os algarismos decimais
  194. */
  195. if (j == 0) { ///< Caso especial
  196. aux[k] = 0;
  197. k++;
  198. }
  199. while (j) {
  200. aux[k] = j % 10;
  201. j = j / 10;
  202. k++;
  203. }
  204. /*!
  205. * Passo 2: representa em ASCII os d&iacute;gitos decimais
  206. */
  207. while (k > 0) {
  208. *s = (aux[k-1] + 0x30);
  209. s++; ///< incrementa o endere&ccedil;o por unidade do tipo de dados
  210. k--;
  211. }
  212. *s = 0;
  213. }
  214.  
  215. /**
  216. * @brief L&ecirc; o valor do pino 12 da porta A
  217. * @param [in] pta 0 (PTA5) ou 1 (PTA12)
  218. * @return estado do bot&atilde;o (0 apertado; 1 normal)
  219. */
  220. //Ting: Precisa?
  221. /*
  222. short le_pta (tipo_pta pta) {
  223. unsigned int a;
  224. short tmp;
  225.  
  226. a = GPIOA_PDIR; ///< Faz a leitura na PORTA (32 bits)
  227. switch (pta) {
  228. case PTA5: tmp = (short) (a & (1<<5));
  229. break;
  230. case PTA12: tmp = (short) (a & (1<<12));
  231. }
  232. return tmp;
  233. }
  234. */
  235. /**
  236. * @brief Intervalo de tempo de aperto
  237. * @param [in] pta 0 (PTA5) ou 1 (PTA12)
  238. * @return m&uacute;ltiplos de 50000*10us (fa&ccedil;a ajustes finos conforme a sua velocidade de aperto)
  239. *
  240. */
  241. /*
  242. uint8_t tempo_espera (tipo_pta pta) {
  243. short estado;
  244. uint8_t i;
  245. uint8_t indice=0;
  246. for (i=0; i < 5; i++) {
  247. delay10us(25000); ///< tempo estimado para o usu&aacute;rio soltar o bot&atilde;o
  248. estado = le_pta(pta);
  249.  
  250. if (estado) return indice;
  251. indice++;
  252. }
  253.  
  254. return indice; ///< atingiu o m&aacute;ximo tempo permitido
  255. }
  256. */
  257. /**
  258. * @brief Seta o estado do led
  259. * @param[in] tipo vermelho, verde e azul
  260. * @param[in] aceso (1) ou apagado (0)
  261. */
  262. void led (tipo_led tipo, estado_led estado) {
  263. switch(tipo)
  264. {
  265. case VERMELHO:
  266. if (estado == ACESO)
  267. GPIOB_PCOR = GPIO_PIN(18); ///< Clear bit 18 de PTB, LED vermelho acende
  268. else
  269. GPIOB_PSOR = GPIO_PIN(18); ///< Set bit 18 de PTB, LED vermelho apaga
  270. break;
  271. case VERDE:
  272. if (estado == ACESO)
  273. GPIOB_PCOR = GPIO_PIN(19); ///< Clear bit 19 de PTB, LED verde acende
  274. else
  275. GPIOB_PSOR = GPIO_PIN(19); ///< Set bit 19 de PTB, LED verde apaga
  276. break;
  277. case AZUL:
  278. if (estado == ACESO)
  279. GPIOD_PCOR = GPIO_PIN(1); ///< Clear bit 1 de PTD, LED azul acende
  280. else
  281. GPIOD_PSOR = GPIO_PIN(1); ///< Set bit 1 de PTD, LED azul apaga
  282. }
  283. }
  284.  
  285. /**
  286. * @brief Espera por um intervalo correspondente &agrave; metade do per&iacute;odo
  287. * correspondente &agrave; frequ&ecirc;ncia especificada
  288. * @param[in] valor
  289. */
  290. void delayfreq(float valor) {
  291. delay10us((int)(1./valor*50000.));
  292. }
  293.  
  294.  
  295. /*!
  296. * \fn InitSysTick (void)
  297. * \brief Inicializa o temporizador SysTick.
  298. */
  299. void InitSysTick (void) {
  300. /*!
  301. * core clock: 20.971520MHz
  302. */
  303. SYST_RVR = SysTick_RVR_RELOAD(0xd1); ///< a) o valor referencia colocado até ainterrupção 1000= 48us ///< peri&oacute;dicas de ~10us?
  304. SYST_CVR = SysTick_CVR_CURRENT(0xd1); ///< b) ESSE QUE É DECREMENTADO
  305. //Ting: use macro para que fica mais facil de entender
  306. //SYST_CSR |= (SysTick_CSR_CLKSOURCE_MASK | ///< configura a fonte de relogio
  307. // 0b11 ); ///< habilita o contador do SysTick e excessão
  308.  
  309. SYST_CSR |= (SysTick_CSR_CLKSOURCE_MASK |
  310. SysTick_CSR_TICKINT_MASK |
  311. SysTick_CSR_ENABLE_MASK);
  312. }
  313.  
  314. /*!
  315. * \fn enableNVIC (void)
  316. * \brief Habilita interrupções via NVIC.
  317. */
  318. void enableNVIC(void) {
  319. /*
  320. * "Non-core interrupt source count" (IRQ = Vector Number (46) - 16,
  321. * Table 3-7 de KL-25 Sub-Family Reference Manual) &eacute; habilitado
  322. * ao escrever 1 no bit correpondente do registrador NVIC_ISER
  323. * (B3.4.3 de ARMv6-M Architecture Reference Manual) e a solicita&ccedil;&atilde;o de
  324. * interrup&ccedil;&atilde;o &eacute; limpa ao escrever 1 no bit correspondente do
  325. * registrador NVIC_ICPR (B3.4.6 de ARMv6-M Architecture Reference Manual)
  326. */
  327. NVIC_ISER |= GPIO_PIN (30); ///< d) Qual é o pino que deve ser setado? Por que?
  328. NVIC_ICPR |= GPIO_PIN (30); ///< e) Qual é o pino que deve ser setado? Por que?
  329. NVIC_IPR7 |= NVIC_IP_PRI_30(0x40); ///< f) Qual eh o nivel de prioridade setado?
  330. NVIC_ISER |= 1 << (12); // i) Habilite interrup&ccedil;&atilde;o UART0
  331. NVIC_ICPR |= 1 << (12); // e limpe as pendencias
  332. NVIC_IPR3 |= NVIC_IP_PRI_12(0x40); ///< j) Sete o nivel de prioridade em 1.
  333. }
  334.  
  335. /*!
  336. * \fn PORTA_IRQHandler (void)
  337. * \brief Rotina de serviço para GPIOA (Vetor 46, IRQ30, prioridade em NVICIPR7[31:30])
  338. */
  339. void PORTA_IRQHandler(void) {
  340. static uint32_t tempo51=0, tempo52=0, tempo121=0, tempo122=0;
  341. float m, v;
  342.  
  343. /*!
  344. * g) O que o registrador SYST_CVR e SYST_RVR armazenam?
  345. * Uma analogia: Imagine calcular o tempo em que um corredor corre em volta de uma pista de cooper de
  346. * circuito fechado. Supondo que voce marcou o instante de inicio (tempo51/tempo121),
  347. * a quantidade de voltas que ele deu na pista (tempo5/tempo12), e registrou
  348. * o instante que ele parou (tempo52/tempo122). Como voce determinaria o tempo
  349. * total v que ele gastou sabendo que cada volta leva SYST_RVR? Como voce computaria
  350. * indice5/indice12 a partir de v como múltiplos de 0.25s? Preencha o código abaixo
  351. * com o seu algoritmo.
  352. */
  353.  
  354. if (PORTA_PCR5 & PORT_PCR_ISF_MASK) {
  355. if (GPIOA_PDIR & GPIO_PIN(5)) { ///< h) Por que esta instrucao consegue
  356. ///< identificar que o estado da botoeira?
  357. /*! Soltou */
  358. estado_pta5 = 1; ///< i) Qual é a funcao desta variável?
  359. tempo52 = SYST_CVR;
  360.  
  361. //Tinf: faltaram os tempos nos extremos ...
  362. // v = (0.00001*tempo5)*4;
  363. if (tempo52 < tempo51) m = (tempo51-tempo52)/((float)(SYST_RVR));
  364. v = (tempo5 > 0)?(tempo5+(SYST_RVR-tempo52+tempo51)/((float)SYST_RVR)):m; ///< computa tempo transcorrido em m?ltiplo de 10us
  365. v *= 0.00004;
  366.  
  367. indice5 = (int)v;
  368. if(v<1) indice5=0;
  369. // Ting: sao 6 ou 7 elementos?
  370. //if (indice5 > 5) indice5 = 5;
  371. if (indice5 > 6) indice5 = 6;
  372. } else {
  373. /*! Apertou */
  374. tempo51 = SYST_CVR;
  375. tempo5 = 0;
  376. }
  377. PORTA_PCR5 |= PORT_PCR_ISF_MASK; ///< j) limpe a solicitacao
  378. ///< Posso remove-la?
  379. } else if (PORTA_PCR12 & PORT_PCR_ISF_MASK) {
  380. if (GPIOA_PDIR & GPIO_PIN(12)) {
  381. /*! Soltou */
  382. estado_pta12 = 1;
  383. tempo122 = SYST_CVR;
  384. //Ting: veja se entendeu ... e ajuste a instrucao
  385. v = (0.00001*tempo12)*4;
  386.  
  387. indice12 = (int)v;
  388. if(v<1) indice12=0;;
  389. // Ting: sao quantos elementos? Corrija por favor ...
  390. if (indice12 > 5) indice12 = 5;
  391. } else {
  392. /*! Apertou */
  393. tempo121 = SYST_CVR;
  394. tempo12 = 0;
  395. }
  396. PORTA_PCR12 |= PORT_PCR_ISF_MASK; ///< j) limpe a solicitacao
  397. }
  398. }
  399.  
  400. /*!
  401. * \fn SysTick_Handler (void)
  402. * \brief Rotina de serviço para exce&ccedil&atilde;o SysTick (Vetor 15)
  403. */
  404. void SysTick_Handler(void) {
  405. /*!
  406. * Qual é a funcao desta rotina? Qual é a periodicidade aproximada
  407. * que esta rotina é chamada?
  408. *
  409. */
  410. tempo++; ///< k) O que tempo, tempo5 e tempo12 armazenam?
  411. tempo5++;
  412. tempo12++;
  413. }
  414.  
  415. /*!
  416. * \fn NMI_Handler
  417. * \brief Rotina de servi&ccedil;o para exce&ccedil;&atilde;o NMI (Vetor 2)
  418. */
  419. void NMI_Handler() {
  420. /*!
  421. * Qual é a funcao desta rotina vazia? O que acontece se removermos esta funcao
  422. * e apertar na botoeira NMI (a primeira das 3 botoeiras)? Por quê?
  423. */
  424. }
  425. /**
  426. * @brief Gera um atraso de t*10us
  427. * @param[in] t m&uacute;ltiplos de 10us
  428. */
  429.  
  430.  
  431. /**
  432. * @brief Inicializa como GPIO A12, B18, B19, C0-10 e D1
  433. */
  434. void inicGPIO(void) {
  435. SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK |
  436. SIM_SCGC5_PORTB_MASK |
  437. SIM_SCGC5_PORTC_MASK |
  438. SIM_SCGC5_PORTD_MASK) ; ///< Habilita os clocks dos módulos
  439.  
  440. /*! Configura os pinos PORTC[10:0] como GPIO de sa&iacute;da */
  441. PORTC_PCR0 = PORT_PCR_MUX(0x1); ///< D0-D7 dos dados (GPIO)
  442. PORTC_PCR1 = PORT_PCR_MUX(0x1);
  443. PORTC_PCR2 = PORT_PCR_MUX(0x1);
  444. PORTC_PCR3 = PORT_PCR_MUX(0x1);
  445. PORTC_PCR4 = PORT_PCR_MUX(0x1);
  446. PORTC_PCR5 = PORT_PCR_MUX(0x1);
  447. PORTC_PCR6 = PORT_PCR_MUX(0x1);
  448. PORTC_PCR7 = PORT_PCR_MUX(0x1);
  449. PORTC_PCR8 = PORT_PCR_MUX(0x1); ///< RS do LCD
  450. PORTC_PCR9 = PORT_PCR_MUX(0x1); ///< E do LCD
  451. PORTC_PCR10 = PORT_PCR_MUX(0x1); ///< /LE do latch
  452.  
  453. GPIOC_PDDR |= GPIO_PDDR_PDD(GPIO_PIN(10) | GPIO_PIN(9) | GPIO_PIN(8) |GPIO_PIN(7) |
  454. GPIO_PIN(6) | GPIO_PIN(5) | GPIO_PIN(4) | GPIO_PIN(3) |
  455. GPIO_PIN(2) | GPIO_PIN(1) | GPIO_PIN(0)); ///< Configura como sa&iacute;das
  456. GPIOC_PDOR &= ~GPIO_PDOR_PDO(GPIO_PIN(10) | GPIO_PIN(9) | GPIO_PIN(8) |GPIO_PIN(7) |
  457. GPIO_PIN(6) | GPIO_PIN(5) | GPIO_PIN(4) | GPIO_PIN(3) |
  458. GPIO_PIN(2) | GPIO_PIN(1) | GPIO_PIN(0)); ///< Inicializa os pinos com 0
  459.  
  460. /*!
  461. * Configura os pinos PORTA[12,5] como GPIO de entrada
  462. */
  463. PORTA_PCR5 |= PORT_PCR_MUX(0x1); ///< Configura como GPIO
  464. PORTA_PCR12 |= PORT_PCR_MUX(0x1); ///< Configura como GPIO
  465.  
  466. /*! Configura a direcao dos pinos 5 e 12 da PORTA como entrada */
  467. GPIOA_PDDR &= ~(GPIO_PDDR_PDD(GPIO_PIN(5)) |
  468. GPIO_PDDR_PDD(GPIO_PIN(12)));
  469.  
  470. PORTA_PCR5 |= PORT_PCR_ISF_MASK |
  471. PORT_PCR_IRQC(0xB); ///< l) condicoes de excecao em ambas as bordas
  472.  
  473. PORTA_PCR12 |= PORT_PCR_ISF_MASK |
  474. PORT_PCR_IRQC(0xB);
  475.  
  476. /*! Configura pino B18 como GPIO (MUX = 001) */
  477. PORTB_PCR18 |= PORT_PCR_MUX(0x1);
  478.  
  479. /*! Configura pino B19 como GPIO (MUX = 001) */
  480. PORTB_PCR19 |= PORT_PCR_MUX(0x1);
  481.  
  482. /*! Configura a direcao dos pinos 18 e 19 da PORTB como sa&iacute;da */
  483. GPIOB_PDDR |= GPIO_PDDR_PDD(GPIO_PIN(18)) |
  484. GPIO_PDDR_PDD(GPIO_PIN(19));
  485.  
  486. /*! Inicializa os pinos 18 e 19 */
  487. GPIOB_PSOR = GPIO_PDDR_PDD(GPIO_PIN(18)) |
  488. GPIO_PDDR_PDD(GPIO_PIN(19));
  489.  
  490. /*! Configura pino D1 como GPIO (MUX = 001) */
  491. PORTD_PCR1 |= PORT_PCR_MUX(0x1);
  492.  
  493. /*! Configura a diire&ccedil;&atilde;o dos pino 1 da PORTD como sa&iacute;da */
  494. GPIOD_PDDR |= GPIO_PDDR_PDD(GPIO_PIN(1));
  495.  
  496. /*! Inicializa o pino 1 */
  497. GPIOD_PSOR |= GPIO_PDDR_PDD(GPIO_PIN(1));
  498. }
  499.  
  500. /*!
  501. * \fn pulso (char p)
  502. * \brief Gera um pulso "Enable" de t*1us.
  503. * \param[in] p para LCD (p=0) e para Leds (p=1).
  504. */
  505. void pulso(tipo_enable p, uint8_t t) {
  506. GPIOC_PSOR = GPIO_PIN (9 + (p)); ///< Seta 1 no PORTC[9+p]
  507.  
  508. GPIOC_PCOR = GPIO_PIN (9 + p); ///< Limpa em 0 o PORTC[9+p]
  509. delay10us(t); ///< mant&eacute;m aprox. t*10us
  510. }
  511.  
  512. /*!
  513. * \fn RS (uint8_t l)
  514. * \brief Envia ao LCD o sinal RS pelo pino PORTC[8].
  515. * \param[in] l valor do RS (0, byte de instru&ccedil;&atilde;o e 1, byte de dados).
  516. */
  517. void RS(uint8_t l) {
  518. if(l) { ///< (l != 0)
  519. GPIOC_PSOR = GPIO_PIN(8); ///< Seta o LCD no modo de dados
  520. } else {
  521. GPIOC_PCOR = GPIO_PIN(8); ///< Seta o LCD no modo de instru&ccedil;&atilde;o
  522. }
  523. }
  524.  
  525. /*!
  526. * \fn enviaLCD (char c)
  527. * \brief Envia ao LCD um byte pelos pinos PORTC[7:0]
  528. * \param[in] c caracter em ASCII.
  529. * \param[in] t tempo de processamento necess&aacute;rio.
  530. */
  531. void enviaLCD(char c, uint8_t t) {
  532. GPIOC_PCOR = 0x000000FF; ///< limpa em 0 PORTC[7:0]
  533. GPIOC_PSOR = (unsigned int)c; ///< Seta os bits que devem ser setados
  534. pulso(0, t); ///< dispara o pulso "Enable" do LCD
  535. }
  536.  
  537. /*!
  538. * \fn inicLCD (void)
  539. * \brief Inicializa o LCD com a sequ&ecirc;ncia de instru&ccedil;&otilde;es recomendada pelo fabricante
  540. */
  541.  
  542. void inicLCD(void) {
  543. int k;
  544. lcd init_LCD[4];
  545.  
  546. /*!
  547. * Instru&ccedil;&otilde;es de inicializa&ccedil;&atilde;o do LCD
  548. */
  549. init_LCD[0].cop = LCD_FUNCTION_SET;
  550. init_LCD[0].tempo = 4;
  551. init_LCD[1].cop = LCD_DISPLAY_CONTROL;
  552. init_LCD[1].tempo = 4;
  553. init_LCD[2].cop = LCD_DISPLAY_CLEAR;
  554. init_LCD[2].tempo = 153;
  555. init_LCD[3].cop = LCD_ENTRY_MODE_SET;
  556. init_LCD[3].tempo = 4;
  557.  
  558. delay10us(4000);
  559.  
  560. RS(0); ///< Seta o LCD no modo de instru&ccedil;&atilde;o
  561. for(k = 0; k < 4; k++) {
  562. enviaLCD(init_LCD[k].cop, init_LCD[k].tempo); ///< instru&ccedil;&atilde;o de inicializa&ccedil;&atilde;o
  563. }
  564. }
  565.  
  566. /*!
  567. * \fn mandaString (char *s)
  568. * \brief Envia uma string de caracteres.
  569. * \param[in] s endere&ccedil;o inicial da string.
  570. */
  571. void mandaString(char * s) {
  572. RS(1); ///< Seta o LCD no modo de dados
  573. while (*s) { ///< enquanto o conte&uacute;do do endere&ccedil;o != 0
  574. //Ting: 43us?
  575. //enviaLCD(*s, 4); ///< envia o byte
  576. enviaLCD(*s, 5); ///< envia o byte
  577. s++; ///< incrementa o endere&ccedil;o
  578. }
  579. }
  580.  
  581. /*!
  582. * \fn enviaLed (char c)
  583. * \brief Envia ao LED um byte pelos pinos PORTC[7:0]
  584. * \param[in] c caracter em ASCII.
  585. * \param[in] t tempo de processamento necess&aacute;rio.
  586. */
  587. void enviaLed(char c) {
  588. GPIOC_PCOR = 0x000000FF; ///< limpa em 0 PORTC[7:0]
  589. GPIOC_PSOR = (unsigned int)c; ///< Seta os bits que devem ser setados
  590. pulso(1, 1); ///< dispara o pulso "Enable" do Latch 74573
  591. }
  592.  
  593. /*
  594. * @brief Mostra a cor dos leds no LCD
  595. * @param[in] ind &indice
  596. */
  597. void mostra_cor_LCD(uint8_t ind)
  598. {
  599.  
  600. /*!
  601. * Mostre a cor no LCD
  602. */
  603. enviaLed(0x01); ///< liga led vermelho 0
  604.  
  605. switch (ind) {
  606. case 0:
  607. mandaString(vermelho);
  608. break;
  609. case 1:
  610. mandaString(branco);
  611. break;
  612. case 2:
  613. mandaString(amarelo);
  614. break;
  615. case 3:
  616. mandaString(ciano);
  617. break;
  618. case 4:
  619. mandaString(magenta);
  620. break;
  621. case 5:
  622. enviaLed(0x00); ///< desliga led vermelho 0
  623. mandaString(preto);
  624. break;
  625. // Ting: faltou led verde ...
  626. case 6:
  627. mandaString(verde);
  628. break;
  629. }
  630.  
  631.  
  632. }
  633.  
  634. int countf(float d){
  635. int i=0;
  636. while(d>1){
  637. d=d/10;
  638. i++;
  639. }
  640. return i;
  641. }
  642.  
  643. void ConvFpraString(float entry, char *finals){
  644. float auxf;
  645. int aux=10, left, right,i;
  646. /*!
  647. * Pega a parte inteira sem arredondar
  648. */
  649. left = (int) entry;
  650. if(left>1){
  651. ConvUIpraDec((float)left,finals);
  652. /*!
  653. * Adiciona ponto na posi??o determinada por contf
  654. */
  655. finals[countf(left)]='.';
  656. i=countf(left)+1;
  657. } else{
  658. finals[0]='0';
  659. finals[1]='.';
  660. i=2;
  661. }
  662. /*!
  663. * Separa a parte menor que zero
  664. */
  665. entry = entry - left;
  666.  
  667. auxf = entry * aux;
  668. /*!
  669. * Pega a parte inteira sem arredondar
  670. */
  671. right = (int)auxf;
  672.  
  673. /*!
  674. * Adiciona a parte menor que zero ap?s o ponto
  675. */
  676. ConvUIpraDec(right,&finals[i]);
  677. }
  678. void criaBitmapI (uint8_t end)
  679. {
  680. /*!
  681. * Esta rotina so tem um argumento que eh o endereco da memoria CGRAM.
  682. * Pressupoe-se que ? so para bitmap "i com acento".
  683. */
  684. RS(0);
  685. //Ting: para que o endere?o seja o do bitmap da Tabela de Fontes e n?o da memoria CGRAM ...
  686. enviaLCD(0x40+(end*8), 4); ///< Set CG RAM Address
  687. RS(1);
  688.  
  689. // Ting: 43us?
  690. /*
  691. enviaLCD(0x2, 4); ///< Set CG RAM Address
  692. enviaLCD(0x4, 4); ///< Set CG RAM Address
  693. enviaLCD(0x0, 4); ///< Set CG RAM Address
  694. enviaLCD(0xc, 4); ///< Set CG RAM Address
  695. enviaLCD(0x4, 4); ///< Set CG RAM Address
  696. enviaLCD(0x4, 4); ///< Set CG RAM Address
  697. enviaLCD(0xe, 4); ///< Set CG RAM Address
  698. enviaLCD(0x0, 4); ///< Set CG RAM Address
  699. */
  700. enviaLCD(0x2, 5); ///< Set CG RAM Address
  701. enviaLCD(0x4, 5); ///< Set CG RAM Address
  702. enviaLCD(0x0, 5); ///< Set CG RAM Address
  703. enviaLCD(0xc, 5); ///< Set CG RAM Address
  704. enviaLCD(0x4, 5); ///< Set CG RAM Address
  705. enviaLCD(0x4, 5); ///< Set CG RAM Address
  706. enviaLCD(0xe, 5); ///< Set CG RAM Address
  707. enviaLCD(0x0, 5); ///< Set CG RAM Address
  708. }
  709. /*!Função converte string para float, parando em inteiro antes do ponto e flutuantedepois do ponto e juntando depois*/
  710. float ConvStringpraF (char *s){
  711. int inteiro,flutuante, aux, i, size,tsize;
  712. float numero;
  713. i=0;
  714. while(s[i]!='.'){
  715. i++;
  716. }
  717. aux=1;
  718. size=i;
  719. inteiro = 0;
  720. while(i-1>=0){
  721. inteiro = (s[i-1]-0x30)*(aux)+ inteiro;
  722. aux=10*aux;
  723. i--;
  724. }
  725.  
  726. i= size + 1;
  727. while(s[i]>=0x30 && s[i]<=0x39 ){
  728. i++;
  729. }
  730. aux=1;
  731. flutuante = 0;
  732. while(i-1>=size+1){
  733. flutuante = (s[i-1]-0x30)*(aux)+ flutuante;
  734. aux=10*aux;
  735. i--;
  736. }
  737.  
  738. numero= ((float)inteiro)+((float)flutuante)/aux;
  739. return numero;
  740. }
  741. /*!Função remove a string do buffer de arcodo com o tamanho entrado chama conversor para float e atribuio o valor a variavel global que controla o periodo*/
  742. void changeTime (short counter){
  743. short aux,i=0;
  744. char s[30];
  745. aux=buffer_uart.head_receptor-counter;
  746. if(aux<0){
  747. aux= MAX + aux;
  748. }
  749. while(aux!=buffer_uart.head_receptor){
  750. s[i]= buffer_uart.receptor[aux];
  751. i++;
  752. aux = (aux + 1)%MAX;
  753. }
  754. temp = ConvStringpraF(&s[0]);
  755. insere_item(TRANSMISSOR, '\n');
  756. insere_item(TRANSMISSOR, '\r');
  757. estado_pta12=1;
  758. }
  759. void insere_item (tipo_buffer b, char d) {
  760. short aux;
  761. static short counter=0;
  762. switch (b) {
  763. case RECEPTOR:
  764. aux = (buffer_uart.head_receptor+1)%MAX;
  765. if (aux == buffer_uart.tail_receptor) {
  766. while (aux == buffer_uart.tail_receptor);
  767. }
  768. buffer_uart.receptor[buffer_uart.head_receptor] = d;
  769. insere_item(TRANSMISSOR, d);
  770. if( d=='\r') {changeTime(counter);counter=0;}else{counter++;}
  771. buffer_uart.head_receptor = aux;
  772. break;
  773. case TRANSMISSOR:
  774. //Ting: o que acha de usar operador modulo?
  775. //if(receptorh>=488) {receptorh=0;}else{receptorh++;};
  776. aux = (buffer_uart.head_transmissor+1)%MAX;
  777. //Ting: quando o buffer esta cheio ...
  778. //while(!((receptorh-receptori>=0 ||(receptori-receptorh>1))&& !(receptorh==488 && receptori==0))){}
  779. if (aux == buffer_uart.tail_transmissor) {
  780. while (aux == buffer_uart.tail_transmissor);
  781. }
  782. //Ting: nao avanca o ponteiro?
  783. //buffer_uart.head_transmissor = 1;
  784. //buffer_uart.transmissor[receptorh] = d;
  785. buffer_uart.transmissor[buffer_uart.head_transmissor] = d;
  786. buffer_uart.head_transmissor = aux;
  787. UART0_C2 |= UART_C2_TIE_MASK; // l) O que este comando faz? para que?
  788.  
  789. break;
  790. }
  791. }
  792.  
  793. char remove_item (tipo_buffer b) {
  794. char d;
  795. switch (b) {
  796. case RECEPTOR:
  797. if(buffer_uart.head_receptor != buffer_uart.tail_receptor){
  798. d = buffer_uart.receptor[buffer_uart.tail_receptor];
  799. buffer_uart.tail_receptor = (buffer_uart.tail_receptor+1)%MAX;
  800. if (buffer_uart.tail_receptor == buffer_uart.head_receptor) buffer_uart.head_receptor = buffer_uart.tail_receptor = 0;
  801. }
  802. break;
  803. case TRANSMISSOR:
  804. //Ting: use o operador modulo
  805. //if(receptori>=488) {receptori=0;}else{receptori++;};
  806. //Ting: Lucas, voce acha que tem sentido zerar? Como o ponteiro desloca?
  807. //buffer_uart.head_transmissor = 0;
  808. //TIng: por que uma outra variavel?
  809. //d = buffer_uart.transmissor[receptori];
  810. if (buffer_uart.head_transmissor != buffer_uart.tail_transmissor) {
  811. d = buffer_uart.transmissor[buffer_uart.tail_transmissor];
  812. buffer_uart.tail_transmissor = (buffer_uart.tail_transmissor+1)%MAX;
  813. } else {
  814. buffer_uart.head_transmissor = buffer_uart.tail_transmissor = 0;
  815. //Ting: buffer vazio ...
  816. UART0_C2 &= ~UART_C2_TIE_MASK; // m) O que este comando faz? para que?
  817. return 0xff; //Ting: caracter que indica "vazio"
  818. }
  819. }
  820. return d;
  821. }
  822.  
  823. void UART0_IRQHandler(void) {
  824. char d;
  825.  
  826. if (UART0_S1 & UART0_S1_RDRF_MASK) // n) Veja que so ha uma excecao associada ao UART0.
  827. // Porem UART0 dispoe de registradores de estado
  828. // que indicam as condicoes de excecao.
  829. // Quais condicoes sao tratadas nesta rotina
  830. // de servico?
  831. {
  832. d = UART0_D;
  833. insere_item(RECEPTOR, d);
  834. } else if (UART0_S1 & UART0_S1_TDRE_MASK) {
  835. UART0_D = remove_item(TRANSMISSOR);
  836. }
  837. }
  838.  
  839.  
  840.  
  841. int main(void){
  842. // Ting: alocacao estatica
  843. //float *freqs;
  844. //char *s ,limpa[]= " ";
  845. int i;
  846. char cors[]="Cor: ";
  847. char periodo[]="Periodo: ";
  848. char s[10];
  849. struct _cor cores_estaticas[] = {{ACESO,APAGADO,APAGADO},{ACESO,ACESO,ACESO},
  850. {ACESO,ACESO,APAGADO},{APAGADO,ACESO,ACESO},
  851. {ACESO,APAGADO,ACESO},{APAGADO,APAGADO,APAGADO},
  852. {APAGADO,ACESO,APAGADO}};
  853. /*!
  854. * Inicializa&ccedil&atilde;o do tSysTick
  855. */
  856. InitSysTick();
  857. /*!
  858. * Inicializa&ccedil;&otilde;es do GPIO do Kinetis
  859. */
  860. inicGPIO();
  861. inicLCD();
  862. initUART();
  863. /*! Inicizlize os buffers auxiliares de UART */
  864. //Ting: Inicializacao
  865. buffer_uart.head_receptor = 0;
  866. buffer_uart.head_transmissor = 0;
  867. buffer_uart.tail_receptor = 0;
  868. buffer_uart.tail_transmissor = 0;
  869. buffer_uart.receptor[0] = 0x00;
  870. //Ting: tem sentido so inicializar um campo?
  871. buffer_uart.transmissor[0] = 0x00;
  872. /*!
  873. * Habilita interrup&ccedil;&atilde;o
  874. */
  875. enableNVIC();
  876.  
  877.  
  878.  
  879.  
  880. /*!
  881. * frequencia alterada para meio per?odo
  882. */
  883. temp = 2000.0;
  884.  
  885.  
  886. /*!
  887. * Execu&ccedil;&atilde;o da tarefa pisca-pisca sob controle
  888. */
  889. /*!
  890. * Maior digito sera 1 do perido 1/0.5, ent?o h? 3 caracteres
  891. */
  892. //s = (char *)malloc(10*sizeof(char));
  893.  
  894. criaBitmapI(0x00);/*!cria o bit map*/
  895.  
  896. //Ting: inicializar com "Cor: " e "Periodo: "
  897.  
  898. RS(0);
  899. enviaLCD(0b10000000, 4); ///< posicione o cursor
  900. mandaString("Cor:"); ///< escreve cor:
  901.  
  902. RS(0);
  903. enviaLCD(0b11000000, 4); ///< posicione o cursor
  904. mandaString("Per"); ///< escreve Periodo:
  905. enviaLCD(0x00,4);
  906. mandaString("odo:"); ///< escreve Periodo:
  907. char *cor;
  908. for(;;){
  909. // Ting: para aumentar a responsividade do sistema ...
  910. inicio: if (estado_pta5 || estado_pta12) {
  911. ConvFpraString(temp,s);
  912. switch (indice5){
  913. case 0:
  914. cor=&vermelho[0];
  915. break;
  916. case 1:
  917. cor=&branco[0];
  918. break;
  919. case 3:
  920. cor=&ciano[0];
  921. break;
  922. case 4:
  923. cor=&magenta[0];
  924. break;
  925. case 5:
  926. cor=&preto[0];
  927. break;
  928. case 6:
  929. cor=&verde[0];
  930. break;
  931. }
  932. i=0;
  933. while (i<4){
  934. insere_item(TRANSMISSOR, cors[i]);
  935. i++;
  936. }
  937. i=0;
  938. while (i<9){
  939. insere_item(TRANSMISSOR, cor[i]);
  940. i++;
  941. }
  942. insere_item(TRANSMISSOR, '\n');
  943. insere_item(TRANSMISSOR, '\r');
  944. i=0;
  945. while (i<8){
  946. insere_item(TRANSMISSOR, periodo[i]);
  947. i++;
  948. }
  949. i=0;
  950. while ((i<8) && (s[i]>=0x30) && (s[i]<=0x39) || (s[i]=='.')){
  951. insere_item(TRANSMISSOR, s[i]);
  952. i++;
  953. }
  954. insere_item(TRANSMISSOR, '\n');
  955. insere_item(TRANSMISSOR, '\r');
  956. estado_pta5=0;
  957. estado_pta12=0;
  958. }
  959. /*! Mostra a cor no LCD */
  960. //RS(0);
  961. //enviaLCD(0b10000000, 4); ///< posicione o cursor
  962. //RS(1);
  963. //mandaString(limpa); ///< limpe os campos
  964. //RS(0);
  965. //enviaLCD(0b10000000, 4); ///< posicione o cursor
  966. //RS(1);
  967. //mandaString("Cor:"); ///< escreve cor:
  968. RS(0);
  969. enviaLCD(0b10000101, 4); ///< posicione o cursor
  970. mostra_cor_LCD(indice5); ///< escreva o nome da cor
  971.  
  972. //RS(0);
  973. //enviaLCD(0b11000000, 4); ///< posicione o cursor
  974. //RS(1);
  975. //mandaString(limpa); ///< limpe os campos
  976. //RS(0);
  977. //enviaLCD(0b11000000, 4); ///< posicione o cursor
  978. //RS(1);
  979. //mandaString("Per"); ///< escreve Periodo:
  980. //enviaLCD(0x00,4);
  981. //mandaString("odo:"); ///< escreve Periodo:
  982. // Ting: o seu calculo eh para unidade segundos ou ms?
  983. //ConvFpraString(1.0/freqs[indice12],s);
  984.  
  985. ConvFpraString(temp,s);
  986. //Ting: reposicionar o cursor no campo dos valores somente
  987. RS(0);
  988. enviaLCD(0b11001000, 4); ///< posicione o cursor
  989. mandaString(" "); //Ting: nao precisa RS(1) porque eh chamada na rotina mandaString
  990. RS(0);
  991. enviaLCD(0b11001000, 4); ///< reposicione o cursor
  992. mandaString(s); ///< escreve cor:
  993. mandaString("ms"); ///< escreve Periodo:
  994. /*!
  995. * Exibe a cor conforme o intervalo de tempo estimado
  996. */
  997. led (VERMELHO, cores_estaticas[indice5].vermelho);
  998. led (VERDE, cores_estaticas[indice5].verde);
  999. led (AZUL, cores_estaticas[indice5].azul);
  1000.  
  1001. // Ting: quando ha alteracao ... novo processamento antes do laco de espera ...
  1002. if (estado_pta5 || estado_pta12) goto inicio;
  1003.  
  1004. /*!
  1005. * Pisca conforme o intervalo de tempo estimado
  1006. */
  1007. //Ting: O que acha de usar delay10us para nao repetir as contas?
  1008. //delayfreq(freqs[indice12]); /*! Espera 1/(2*freqs[indice12]) */
  1009.  
  1010. delay10us(temp*50);
  1011.  
  1012. GPIOB_PSOR |= (1<<18) | (1<<19); /*! Set bit 18 e 19, LED vermelho em PTB18 e LED verde em PTB19 (apaga) */
  1013. GPIOD_PSOR |= (1<<1); /*! Set bit 1, LED azul em PTD1(apaga) */
  1014.  
  1015. // Ting: quando ha alteracao ... novo processamento antes do laco de espera ...
  1016. if (estado_pta5 || estado_pta12) goto inicio;
  1017.  
  1018. //Ting: O que acha de usar delay10us para nao repetir as contas?
  1019. // delayfreq(freqs[indice12]);
  1020. delay10us(temp*50);
  1021. }
  1022.  
  1023. /*!
  1024. * Libera o espa&ccedil;o da mem&oacute;ria alocada dinamicamente
  1025. */
  1026. // Ting : deveria ter desalocado s!!!
  1027. //free((void *)freqs);
  1028.  
  1029. return 1;
  1030. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement