Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /*!
- * \file main.c
- * \brief Renderização dos caracteres ASCII em LCD
- *
- * \details Este código ilustra a inicialização e a transferência de dados entre
- * um LCD e o MKZ25Z128 através de uma interface paralela.
- * \mainpage Projeto de identificação de intervalo de tempo em que se mantém um push-button pressionado.
- * \author Wu Shin-Ting edited by Lucas Perissinotto 158149
- * \date 20/10/2016
- * \note Documentação do código no formato de Doxygen:
- * http://mcuoneclipse.com/2014/09/01/automatic-documentation-generation-doxygen-with-processor-expert/
- */
- #include "derivative.h" ///< include peripheral declarations
- #include "stdlib.h" ///< include peripheral declarations
- #include "string.h" ///< include memory operation functions
- /*
- * Enumeração das cores do led
- */
- typedef enum _tipo_led {
- VERMELHO, /*!< vermelho */
- VERDE, /*!< verde */
- AZUL /*! azul */
- } tipo_led;
- /*
- * Enumeração dos estados do led
- */
- typedef enum _estado_led {
- ACESO, /*!< aceso */
- APAGADO /*!< apagado */
- } estado_led;
- /*
- * Enumeração da botoeira
- */
- typedef enum _tipo_pta {
- PTA5, /*!< pino 5 da porta A */
- PTA12 /*!< pino 12 da porta A */
- } tipo_pta;
- /*
- * Enumeração do sinal de Enable
- */
- typedef enum _tipo_enable {
- LCD, /*!< sinal Enable do LCD */
- LEDS /*!< sinal Enable dos Leds */
- } tipo_enable;
- /*
- * Estrutura para representar uma cor pelos estados dos 3 leds
- */
- typedef struct _cor {
- enum _estado_led vermelho; /*!< estado do led vermelho */
- enum _estado_led verde; /*!< estado do led verde */
- enum _estado_led azul; /*!< estado do led azul */
- } cor;
- typedef enum _tipo_buffer {
- RECEPTOR,
- TRANSMISSOR
- } tipo_buffer;
- #define MAX 488
- struct _buffer_uart {
- short head_receptor;
- short tail_receptor;
- char receptor[MAX];
- short head_transmissor;
- short tail_transmissor;
- //char transmissor[4880];
- char transmissor[MAX];
- } buffer_uart;
- void initUART(void) {
- /*!
- * Configuração de SIM
- */
- SIM_CLKDIV1 &= (uint32_t)~(uint32_t)(SIM_CLKDIV1_OUTDIV4(0x7)); ////< bus_clock = clock/1
- SIM_SCGC5 |= SIM_SCGC5_PORTA_MASK;
- SIM_SCGC4 |= SIM_SCGC4_UART0_MASK;
- SIM_SOPT2 |= SIM_SOPT2_UART0SRC(0x1); ///< configura a fonte de relógio (20.971520MHz)
- SIM_SOPT2 &= ~SIM_SOPT2_PLLFLLSEL_MASK;
- ///< no reset, o valor é zero (FLL)
- ///< mas não deixa de ser uma boa
- ///< prática de inicializar explicitamente
- /*!
- * Configuração dos pinos que servem UART0
- */
- PORTA_PCR1 |= PORT_PCR_MUX(0x2); ///< UART0_RX
- PORTA_PCR2 |= PORT_PCR_MUX(0x2); ///< UART0_TX
- /*!
- * Configuração do módulo UART0
- */
- UART0_C1 &= ~(UART0_C1_PE_MASK | // a) Configure "no paridade"
- UART0_C1_ILT_MASK |
- UART0_C1_WAKE_MASK | // b) Configure "idle-line wakep" na recepcao
- UART0_C1_M_MASK | // Configure "dados de 8 bits"
- UART0_C1_DOZEEN_MASK |
- UART0_C1_LOOPS_MASK );
- UART0_C2 &= ~(UART_C2_RE_MASK | // c) Por quê desabilita os dois canais:
- // receptor e transmissor?
- UART_C2_TE_MASK);
- UART0_BDH &= ~(UART_BDH_SBNS_MASK | // d) Configure "1 stop bits"
- UART_BDH_RXEDGIE_MASK |
- UART_BDH_LBKDIE_MASK);
- UART0_C4 |= UART0_C4_OSR(0xF); // e) Configure "taxa de amostragem 16".
- // Compare com a forma de configuracao no
- // programa "exp6_polling.c" e justifique
- // a diferenca.
- /*!
- * baud rate 19200 (Seção 8.3.2 em
- * ftp://ftp.dca.fee.unicamp.br/pub/docs/ea871/ARM/KLQRUG.pdf)
- */
- UART0_BDH |= UART_BDH_SBR(0x00);
- UART0_BDL |= UART_BDL_SBR(0x44); ///< f) Configure baud rate 19200
- UART0_S1 |= (UART0_S1_PF_MASK | ///< Registradores de estado: w1c
- UART0_S1_FE_MASK |
- UART0_S1_NF_MASK |
- UART0_S1_OR_MASK |
- UART0_S1_IDLE_MASK);
- UART0_C2 |= (UART_C2_RIE_MASK | ///< ativa interrupção de recepção
- UART_C2_RE_MASK | ///< habilita o canal receptor
- UART_C2_TE_MASK); ///< habilita o canal transmissor
- ///< g) por que nao e ativada a interrupcao do transmissor?
- // h) No programa "exp6_polling.c" setamos um campo do registrador UARTx_C5. Por que
- // neste programa nao?
- }
- /*
- * Estrutura para representar a instru??o do LCD e o seu tempo de processamento
- */
- typedef struct _lcd {
- uint8_t cop;
- uint8_t tempo;
- } lcd;
- #define GPIO_PIN(x) ((1)<<(x)) ///< obtem o bit do pino x
- #define LCD_FUNCTION_SET 0x38
- #define LCD_DISPLAY_CONTROL 0x0C
- #define LCD_DISPLAY_CLEAR 0x01
- #define LCD_ENTRY_MODE_SET 0x06
- unsigned int tempo, tempo5, tempo12; ///< múltiplo de 10us
- uint8_t estado_pta5, estado_pta12;
- uint8_t indice5 = 5, indice12 = 5;
- float temp;
- /*! Declara??o dos nomes das cores */
- //Ting: inserir espacos para evitar "limpa"
- /*
- char vermelho[] = "VERMELHO";
- char branco[] = "BRANCO";
- char amarelo[] = "AMARELO";
- char ciano[] = "CIANO";
- char magenta[] = "MAGENTA";
- char preto[] = "PRETO";
- */
- char vermelho[] = "VERMELHO";
- char branco[] = "BRANCO ";
- char amarelo[] = "AMARELO ";
- char ciano[] = "CIANO ";
- char magenta[] = "MAGENTA ";
- char preto[] = "PRETO ";
- // Ting: verde
- char verde[] = "VERDE ";
- void delay10us (unsigned int t)
- {
- tempo = 0;
- while (tempo < t) {}
- }
- /*!
- * \fn ConvUIpraDec(unsigned int j, char * s)
- * \brief Converte em ASCII o inteiro sem sinal j.
- * \param[in] j valor inteiro sem sinal
- * \param[out] s representação em ASCII
- */
- void ConvUIpraDec (unsigned int j, char * s) {
- short k = 0;
- char aux[11];
- /*!
- * Passo 1: extrai os algarismos decimais
- */
- if (j == 0) { ///< Caso especial
- aux[k] = 0;
- k++;
- }
- while (j) {
- aux[k] = j % 10;
- j = j / 10;
- k++;
- }
- /*!
- * Passo 2: representa em ASCII os dígitos decimais
- */
- while (k > 0) {
- *s = (aux[k-1] + 0x30);
- s++; ///< incrementa o endereço por unidade do tipo de dados
- k--;
- }
- *s = 0;
- }
- /**
- * @brief Lê o valor do pino 12 da porta A
- * @param [in] pta 0 (PTA5) ou 1 (PTA12)
- * @return estado do botão (0 apertado; 1 normal)
- */
- //Ting: Precisa?
- /*
- short le_pta (tipo_pta pta) {
- unsigned int a;
- short tmp;
- a = GPIOA_PDIR; ///< Faz a leitura na PORTA (32 bits)
- switch (pta) {
- case PTA5: tmp = (short) (a & (1<<5));
- break;
- case PTA12: tmp = (short) (a & (1<<12));
- }
- return tmp;
- }
- */
- /**
- * @brief Intervalo de tempo de aperto
- * @param [in] pta 0 (PTA5) ou 1 (PTA12)
- * @return múltiplos de 50000*10us (faça ajustes finos conforme a sua velocidade de aperto)
- *
- */
- /*
- uint8_t tempo_espera (tipo_pta pta) {
- short estado;
- uint8_t i;
- uint8_t indice=0;
- for (i=0; i < 5; i++) {
- delay10us(25000); ///< tempo estimado para o usuário soltar o botão
- estado = le_pta(pta);
- if (estado) return indice;
- indice++;
- }
- return indice; ///< atingiu o máximo tempo permitido
- }
- */
- /**
- * @brief Seta o estado do led
- * @param[in] tipo vermelho, verde e azul
- * @param[in] aceso (1) ou apagado (0)
- */
- void led (tipo_led tipo, estado_led estado) {
- switch(tipo)
- {
- case VERMELHO:
- if (estado == ACESO)
- GPIOB_PCOR = GPIO_PIN(18); ///< Clear bit 18 de PTB, LED vermelho acende
- else
- GPIOB_PSOR = GPIO_PIN(18); ///< Set bit 18 de PTB, LED vermelho apaga
- break;
- case VERDE:
- if (estado == ACESO)
- GPIOB_PCOR = GPIO_PIN(19); ///< Clear bit 19 de PTB, LED verde acende
- else
- GPIOB_PSOR = GPIO_PIN(19); ///< Set bit 19 de PTB, LED verde apaga
- break;
- case AZUL:
- if (estado == ACESO)
- GPIOD_PCOR = GPIO_PIN(1); ///< Clear bit 1 de PTD, LED azul acende
- else
- GPIOD_PSOR = GPIO_PIN(1); ///< Set bit 1 de PTD, LED azul apaga
- }
- }
- /**
- * @brief Espera por um intervalo correspondente à metade do período
- * correspondente à frequência especificada
- * @param[in] valor
- */
- void delayfreq(float valor) {
- delay10us((int)(1./valor*50000.));
- }
- /*!
- * \fn InitSysTick (void)
- * \brief Inicializa o temporizador SysTick.
- */
- void InitSysTick (void) {
- /*!
- * core clock: 20.971520MHz
- */
- SYST_RVR = SysTick_RVR_RELOAD(0xd1); ///< a) o valor referencia colocado até ainterrupção 1000= 48us ///< periódicas de ~10us?
- SYST_CVR = SysTick_CVR_CURRENT(0xd1); ///< b) ESSE QUE É DECREMENTADO
- //Ting: use macro para que fica mais facil de entender
- //SYST_CSR |= (SysTick_CSR_CLKSOURCE_MASK | ///< configura a fonte de relogio
- // 0b11 ); ///< habilita o contador do SysTick e excessão
- SYST_CSR |= (SysTick_CSR_CLKSOURCE_MASK |
- SysTick_CSR_TICKINT_MASK |
- SysTick_CSR_ENABLE_MASK);
- }
- /*!
- * \fn enableNVIC (void)
- * \brief Habilita interrupções via NVIC.
- */
- void enableNVIC(void) {
- /*
- * "Non-core interrupt source count" (IRQ = Vector Number (46) - 16,
- * Table 3-7 de KL-25 Sub-Family Reference Manual) é habilitado
- * ao escrever 1 no bit correpondente do registrador NVIC_ISER
- * (B3.4.3 de ARMv6-M Architecture Reference Manual) e a solicitação de
- * interrupção é limpa ao escrever 1 no bit correspondente do
- * registrador NVIC_ICPR (B3.4.6 de ARMv6-M Architecture Reference Manual)
- */
- NVIC_ISER |= GPIO_PIN (30); ///< d) Qual é o pino que deve ser setado? Por que?
- NVIC_ICPR |= GPIO_PIN (30); ///< e) Qual é o pino que deve ser setado? Por que?
- NVIC_IPR7 |= NVIC_IP_PRI_30(0x40); ///< f) Qual eh o nivel de prioridade setado?
- NVIC_ISER |= 1 << (12); // i) Habilite interrupção UART0
- NVIC_ICPR |= 1 << (12); // e limpe as pendencias
- NVIC_IPR3 |= NVIC_IP_PRI_12(0x40); ///< j) Sete o nivel de prioridade em 1.
- }
- /*!
- * \fn PORTA_IRQHandler (void)
- * \brief Rotina de serviço para GPIOA (Vetor 46, IRQ30, prioridade em NVICIPR7[31:30])
- */
- void PORTA_IRQHandler(void) {
- static uint32_t tempo51=0, tempo52=0, tempo121=0, tempo122=0;
- float m, v;
- /*!
- * g) O que o registrador SYST_CVR e SYST_RVR armazenam?
- * Uma analogia: Imagine calcular o tempo em que um corredor corre em volta de uma pista de cooper de
- * circuito fechado. Supondo que voce marcou o instante de inicio (tempo51/tempo121),
- * a quantidade de voltas que ele deu na pista (tempo5/tempo12), e registrou
- * o instante que ele parou (tempo52/tempo122). Como voce determinaria o tempo
- * total v que ele gastou sabendo que cada volta leva SYST_RVR? Como voce computaria
- * indice5/indice12 a partir de v como múltiplos de 0.25s? Preencha o código abaixo
- * com o seu algoritmo.
- */
- if (PORTA_PCR5 & PORT_PCR_ISF_MASK) {
- if (GPIOA_PDIR & GPIO_PIN(5)) { ///< h) Por que esta instrucao consegue
- ///< identificar que o estado da botoeira?
- /*! Soltou */
- estado_pta5 = 1; ///< i) Qual é a funcao desta variável?
- tempo52 = SYST_CVR;
- //Tinf: faltaram os tempos nos extremos ...
- // v = (0.00001*tempo5)*4;
- if (tempo52 < tempo51) m = (tempo51-tempo52)/((float)(SYST_RVR));
- v = (tempo5 > 0)?(tempo5+(SYST_RVR-tempo52+tempo51)/((float)SYST_RVR)):m; ///< computa tempo transcorrido em m?ltiplo de 10us
- v *= 0.00004;
- indice5 = (int)v;
- if(v<1) indice5=0;
- // Ting: sao 6 ou 7 elementos?
- //if (indice5 > 5) indice5 = 5;
- if (indice5 > 6) indice5 = 6;
- } else {
- /*! Apertou */
- tempo51 = SYST_CVR;
- tempo5 = 0;
- }
- PORTA_PCR5 |= PORT_PCR_ISF_MASK; ///< j) limpe a solicitacao
- ///< Posso remove-la?
- } else if (PORTA_PCR12 & PORT_PCR_ISF_MASK) {
- if (GPIOA_PDIR & GPIO_PIN(12)) {
- /*! Soltou */
- estado_pta12 = 1;
- tempo122 = SYST_CVR;
- //Ting: veja se entendeu ... e ajuste a instrucao
- v = (0.00001*tempo12)*4;
- indice12 = (int)v;
- if(v<1) indice12=0;;
- // Ting: sao quantos elementos? Corrija por favor ...
- if (indice12 > 5) indice12 = 5;
- } else {
- /*! Apertou */
- tempo121 = SYST_CVR;
- tempo12 = 0;
- }
- PORTA_PCR12 |= PORT_PCR_ISF_MASK; ///< j) limpe a solicitacao
- }
- }
- /*!
- * \fn SysTick_Handler (void)
- * \brief Rotina de serviço para exceção SysTick (Vetor 15)
- */
- void SysTick_Handler(void) {
- /*!
- * Qual é a funcao desta rotina? Qual é a periodicidade aproximada
- * que esta rotina é chamada?
- *
- */
- tempo++; ///< k) O que tempo, tempo5 e tempo12 armazenam?
- tempo5++;
- tempo12++;
- }
- /*!
- * \fn NMI_Handler
- * \brief Rotina de serviço para exceção NMI (Vetor 2)
- */
- void NMI_Handler() {
- /*!
- * Qual é a funcao desta rotina vazia? O que acontece se removermos esta funcao
- * e apertar na botoeira NMI (a primeira das 3 botoeiras)? Por quê?
- */
- }
- /**
- * @brief Gera um atraso de t*10us
- * @param[in] t múltiplos de 10us
- */
- /**
- * @brief Inicializa como GPIO A12, B18, B19, C0-10 e D1
- */
- void inicGPIO(void) {
- SIM_SCGC5 |= (SIM_SCGC5_PORTA_MASK |
- SIM_SCGC5_PORTB_MASK |
- SIM_SCGC5_PORTC_MASK |
- SIM_SCGC5_PORTD_MASK) ; ///< Habilita os clocks dos módulos
- /*! Configura os pinos PORTC[10:0] como GPIO de saída */
- PORTC_PCR0 = PORT_PCR_MUX(0x1); ///< D0-D7 dos dados (GPIO)
- PORTC_PCR1 = PORT_PCR_MUX(0x1);
- PORTC_PCR2 = PORT_PCR_MUX(0x1);
- PORTC_PCR3 = PORT_PCR_MUX(0x1);
- PORTC_PCR4 = PORT_PCR_MUX(0x1);
- PORTC_PCR5 = PORT_PCR_MUX(0x1);
- PORTC_PCR6 = PORT_PCR_MUX(0x1);
- PORTC_PCR7 = PORT_PCR_MUX(0x1);
- PORTC_PCR8 = PORT_PCR_MUX(0x1); ///< RS do LCD
- PORTC_PCR9 = PORT_PCR_MUX(0x1); ///< E do LCD
- PORTC_PCR10 = PORT_PCR_MUX(0x1); ///< /LE do latch
- GPIOC_PDDR |= GPIO_PDDR_PDD(GPIO_PIN(10) | GPIO_PIN(9) | GPIO_PIN(8) |GPIO_PIN(7) |
- GPIO_PIN(6) | GPIO_PIN(5) | GPIO_PIN(4) | GPIO_PIN(3) |
- GPIO_PIN(2) | GPIO_PIN(1) | GPIO_PIN(0)); ///< Configura como saídas
- GPIOC_PDOR &= ~GPIO_PDOR_PDO(GPIO_PIN(10) | GPIO_PIN(9) | GPIO_PIN(8) |GPIO_PIN(7) |
- GPIO_PIN(6) | GPIO_PIN(5) | GPIO_PIN(4) | GPIO_PIN(3) |
- GPIO_PIN(2) | GPIO_PIN(1) | GPIO_PIN(0)); ///< Inicializa os pinos com 0
- /*!
- * Configura os pinos PORTA[12,5] como GPIO de entrada
- */
- PORTA_PCR5 |= PORT_PCR_MUX(0x1); ///< Configura como GPIO
- PORTA_PCR12 |= PORT_PCR_MUX(0x1); ///< Configura como GPIO
- /*! Configura a direcao dos pinos 5 e 12 da PORTA como entrada */
- GPIOA_PDDR &= ~(GPIO_PDDR_PDD(GPIO_PIN(5)) |
- GPIO_PDDR_PDD(GPIO_PIN(12)));
- PORTA_PCR5 |= PORT_PCR_ISF_MASK |
- PORT_PCR_IRQC(0xB); ///< l) condicoes de excecao em ambas as bordas
- PORTA_PCR12 |= PORT_PCR_ISF_MASK |
- PORT_PCR_IRQC(0xB);
- /*! Configura pino B18 como GPIO (MUX = 001) */
- PORTB_PCR18 |= PORT_PCR_MUX(0x1);
- /*! Configura pino B19 como GPIO (MUX = 001) */
- PORTB_PCR19 |= PORT_PCR_MUX(0x1);
- /*! Configura a direcao dos pinos 18 e 19 da PORTB como saída */
- GPIOB_PDDR |= GPIO_PDDR_PDD(GPIO_PIN(18)) |
- GPIO_PDDR_PDD(GPIO_PIN(19));
- /*! Inicializa os pinos 18 e 19 */
- GPIOB_PSOR = GPIO_PDDR_PDD(GPIO_PIN(18)) |
- GPIO_PDDR_PDD(GPIO_PIN(19));
- /*! Configura pino D1 como GPIO (MUX = 001) */
- PORTD_PCR1 |= PORT_PCR_MUX(0x1);
- /*! Configura a diireção dos pino 1 da PORTD como saída */
- GPIOD_PDDR |= GPIO_PDDR_PDD(GPIO_PIN(1));
- /*! Inicializa o pino 1 */
- GPIOD_PSOR |= GPIO_PDDR_PDD(GPIO_PIN(1));
- }
- /*!
- * \fn pulso (char p)
- * \brief Gera um pulso "Enable" de t*1us.
- * \param[in] p para LCD (p=0) e para Leds (p=1).
- */
- void pulso(tipo_enable p, uint8_t t) {
- GPIOC_PSOR = GPIO_PIN (9 + (p)); ///< Seta 1 no PORTC[9+p]
- GPIOC_PCOR = GPIO_PIN (9 + p); ///< Limpa em 0 o PORTC[9+p]
- delay10us(t); ///< mantém aprox. t*10us
- }
- /*!
- * \fn RS (uint8_t l)
- * \brief Envia ao LCD o sinal RS pelo pino PORTC[8].
- * \param[in] l valor do RS (0, byte de instrução e 1, byte de dados).
- */
- void RS(uint8_t l) {
- if(l) { ///< (l != 0)
- GPIOC_PSOR = GPIO_PIN(8); ///< Seta o LCD no modo de dados
- } else {
- GPIOC_PCOR = GPIO_PIN(8); ///< Seta o LCD no modo de instrução
- }
- }
- /*!
- * \fn enviaLCD (char c)
- * \brief Envia ao LCD um byte pelos pinos PORTC[7:0]
- * \param[in] c caracter em ASCII.
- * \param[in] t tempo de processamento necessário.
- */
- void enviaLCD(char c, uint8_t t) {
- GPIOC_PCOR = 0x000000FF; ///< limpa em 0 PORTC[7:0]
- GPIOC_PSOR = (unsigned int)c; ///< Seta os bits que devem ser setados
- pulso(0, t); ///< dispara o pulso "Enable" do LCD
- }
- /*!
- * \fn inicLCD (void)
- * \brief Inicializa o LCD com a sequência de instruções recomendada pelo fabricante
- */
- void inicLCD(void) {
- int k;
- lcd init_LCD[4];
- /*!
- * Instruções de inicialização do LCD
- */
- init_LCD[0].cop = LCD_FUNCTION_SET;
- init_LCD[0].tempo = 4;
- init_LCD[1].cop = LCD_DISPLAY_CONTROL;
- init_LCD[1].tempo = 4;
- init_LCD[2].cop = LCD_DISPLAY_CLEAR;
- init_LCD[2].tempo = 153;
- init_LCD[3].cop = LCD_ENTRY_MODE_SET;
- init_LCD[3].tempo = 4;
- delay10us(4000);
- RS(0); ///< Seta o LCD no modo de instrução
- for(k = 0; k < 4; k++) {
- enviaLCD(init_LCD[k].cop, init_LCD[k].tempo); ///< instrução de inicialização
- }
- }
- /*!
- * \fn mandaString (char *s)
- * \brief Envia uma string de caracteres.
- * \param[in] s endereço inicial da string.
- */
- void mandaString(char * s) {
- RS(1); ///< Seta o LCD no modo de dados
- while (*s) { ///< enquanto o conteúdo do endereço != 0
- //Ting: 43us?
- //enviaLCD(*s, 4); ///< envia o byte
- enviaLCD(*s, 5); ///< envia o byte
- s++; ///< incrementa o endereço
- }
- }
- /*!
- * \fn enviaLed (char c)
- * \brief Envia ao LED um byte pelos pinos PORTC[7:0]
- * \param[in] c caracter em ASCII.
- * \param[in] t tempo de processamento necessário.
- */
- void enviaLed(char c) {
- GPIOC_PCOR = 0x000000FF; ///< limpa em 0 PORTC[7:0]
- GPIOC_PSOR = (unsigned int)c; ///< Seta os bits que devem ser setados
- pulso(1, 1); ///< dispara o pulso "Enable" do Latch 74573
- }
- /*
- * @brief Mostra a cor dos leds no LCD
- * @param[in] ind &indice
- */
- void mostra_cor_LCD(uint8_t ind)
- {
- /*!
- * Mostre a cor no LCD
- */
- enviaLed(0x01); ///< liga led vermelho 0
- switch (ind) {
- case 0:
- mandaString(vermelho);
- break;
- case 1:
- mandaString(branco);
- break;
- case 2:
- mandaString(amarelo);
- break;
- case 3:
- mandaString(ciano);
- break;
- case 4:
- mandaString(magenta);
- break;
- case 5:
- enviaLed(0x00); ///< desliga led vermelho 0
- mandaString(preto);
- break;
- // Ting: faltou led verde ...
- case 6:
- mandaString(verde);
- break;
- }
- }
- int countf(float d){
- int i=0;
- while(d>1){
- d=d/10;
- i++;
- }
- return i;
- }
- void ConvFpraString(float entry, char *finals){
- float auxf;
- int aux=10, left, right,i;
- /*!
- * Pega a parte inteira sem arredondar
- */
- left = (int) entry;
- if(left>1){
- ConvUIpraDec((float)left,finals);
- /*!
- * Adiciona ponto na posi??o determinada por contf
- */
- finals[countf(left)]='.';
- i=countf(left)+1;
- } else{
- finals[0]='0';
- finals[1]='.';
- i=2;
- }
- /*!
- * Separa a parte menor que zero
- */
- entry = entry - left;
- auxf = entry * aux;
- /*!
- * Pega a parte inteira sem arredondar
- */
- right = (int)auxf;
- /*!
- * Adiciona a parte menor que zero ap?s o ponto
- */
- ConvUIpraDec(right,&finals[i]);
- }
- void criaBitmapI (uint8_t end)
- {
- /*!
- * Esta rotina so tem um argumento que eh o endereco da memoria CGRAM.
- * Pressupoe-se que ? so para bitmap "i com acento".
- */
- RS(0);
- //Ting: para que o endere?o seja o do bitmap da Tabela de Fontes e n?o da memoria CGRAM ...
- enviaLCD(0x40+(end*8), 4); ///< Set CG RAM Address
- RS(1);
- // Ting: 43us?
- /*
- enviaLCD(0x2, 4); ///< Set CG RAM Address
- enviaLCD(0x4, 4); ///< Set CG RAM Address
- enviaLCD(0x0, 4); ///< Set CG RAM Address
- enviaLCD(0xc, 4); ///< Set CG RAM Address
- enviaLCD(0x4, 4); ///< Set CG RAM Address
- enviaLCD(0x4, 4); ///< Set CG RAM Address
- enviaLCD(0xe, 4); ///< Set CG RAM Address
- enviaLCD(0x0, 4); ///< Set CG RAM Address
- */
- enviaLCD(0x2, 5); ///< Set CG RAM Address
- enviaLCD(0x4, 5); ///< Set CG RAM Address
- enviaLCD(0x0, 5); ///< Set CG RAM Address
- enviaLCD(0xc, 5); ///< Set CG RAM Address
- enviaLCD(0x4, 5); ///< Set CG RAM Address
- enviaLCD(0x4, 5); ///< Set CG RAM Address
- enviaLCD(0xe, 5); ///< Set CG RAM Address
- enviaLCD(0x0, 5); ///< Set CG RAM Address
- }
- /*!Função converte string para float, parando em inteiro antes do ponto e flutuantedepois do ponto e juntando depois*/
- float ConvStringpraF (char *s){
- int inteiro,flutuante, aux, i, size,tsize;
- float numero;
- i=0;
- while(s[i]!='.'){
- i++;
- }
- aux=1;
- size=i;
- inteiro = 0;
- while(i-1>=0){
- inteiro = (s[i-1]-0x30)*(aux)+ inteiro;
- aux=10*aux;
- i--;
- }
- i= size + 1;
- while(s[i]>=0x30 && s[i]<=0x39 ){
- i++;
- }
- aux=1;
- flutuante = 0;
- while(i-1>=size+1){
- flutuante = (s[i-1]-0x30)*(aux)+ flutuante;
- aux=10*aux;
- i--;
- }
- numero= ((float)inteiro)+((float)flutuante)/aux;
- return numero;
- }
- /*!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*/
- void changeTime (short counter){
- short aux,i=0;
- char s[30];
- aux=buffer_uart.head_receptor-counter;
- if(aux<0){
- aux= MAX + aux;
- }
- while(aux!=buffer_uart.head_receptor){
- s[i]= buffer_uart.receptor[aux];
- i++;
- aux = (aux + 1)%MAX;
- }
- temp = ConvStringpraF(&s[0]);
- insere_item(TRANSMISSOR, '\n');
- insere_item(TRANSMISSOR, '\r');
- estado_pta12=1;
- }
- void insere_item (tipo_buffer b, char d) {
- short aux;
- static short counter=0;
- switch (b) {
- case RECEPTOR:
- aux = (buffer_uart.head_receptor+1)%MAX;
- if (aux == buffer_uart.tail_receptor) {
- while (aux == buffer_uart.tail_receptor);
- }
- buffer_uart.receptor[buffer_uart.head_receptor] = d;
- insere_item(TRANSMISSOR, d);
- if( d=='\r') {changeTime(counter);counter=0;}else{counter++;}
- buffer_uart.head_receptor = aux;
- break;
- case TRANSMISSOR:
- //Ting: o que acha de usar operador modulo?
- //if(receptorh>=488) {receptorh=0;}else{receptorh++;};
- aux = (buffer_uart.head_transmissor+1)%MAX;
- //Ting: quando o buffer esta cheio ...
- //while(!((receptorh-receptori>=0 ||(receptori-receptorh>1))&& !(receptorh==488 && receptori==0))){}
- if (aux == buffer_uart.tail_transmissor) {
- while (aux == buffer_uart.tail_transmissor);
- }
- //Ting: nao avanca o ponteiro?
- //buffer_uart.head_transmissor = 1;
- //buffer_uart.transmissor[receptorh] = d;
- buffer_uart.transmissor[buffer_uart.head_transmissor] = d;
- buffer_uart.head_transmissor = aux;
- UART0_C2 |= UART_C2_TIE_MASK; // l) O que este comando faz? para que?
- break;
- }
- }
- char remove_item (tipo_buffer b) {
- char d;
- switch (b) {
- case RECEPTOR:
- if(buffer_uart.head_receptor != buffer_uart.tail_receptor){
- d = buffer_uart.receptor[buffer_uart.tail_receptor];
- buffer_uart.tail_receptor = (buffer_uart.tail_receptor+1)%MAX;
- if (buffer_uart.tail_receptor == buffer_uart.head_receptor) buffer_uart.head_receptor = buffer_uart.tail_receptor = 0;
- }
- break;
- case TRANSMISSOR:
- //Ting: use o operador modulo
- //if(receptori>=488) {receptori=0;}else{receptori++;};
- //Ting: Lucas, voce acha que tem sentido zerar? Como o ponteiro desloca?
- //buffer_uart.head_transmissor = 0;
- //TIng: por que uma outra variavel?
- //d = buffer_uart.transmissor[receptori];
- if (buffer_uart.head_transmissor != buffer_uart.tail_transmissor) {
- d = buffer_uart.transmissor[buffer_uart.tail_transmissor];
- buffer_uart.tail_transmissor = (buffer_uart.tail_transmissor+1)%MAX;
- } else {
- buffer_uart.head_transmissor = buffer_uart.tail_transmissor = 0;
- //Ting: buffer vazio ...
- UART0_C2 &= ~UART_C2_TIE_MASK; // m) O que este comando faz? para que?
- return 0xff; //Ting: caracter que indica "vazio"
- }
- }
- return d;
- }
- void UART0_IRQHandler(void) {
- char d;
- if (UART0_S1 & UART0_S1_RDRF_MASK) // n) Veja que so ha uma excecao associada ao UART0.
- // Porem UART0 dispoe de registradores de estado
- // que indicam as condicoes de excecao.
- // Quais condicoes sao tratadas nesta rotina
- // de servico?
- {
- d = UART0_D;
- insere_item(RECEPTOR, d);
- } else if (UART0_S1 & UART0_S1_TDRE_MASK) {
- UART0_D = remove_item(TRANSMISSOR);
- }
- }
- int main(void){
- // Ting: alocacao estatica
- //float *freqs;
- //char *s ,limpa[]= " ";
- int i;
- char cors[]="Cor: ";
- char periodo[]="Periodo: ";
- char s[10];
- struct _cor cores_estaticas[] = {{ACESO,APAGADO,APAGADO},{ACESO,ACESO,ACESO},
- {ACESO,ACESO,APAGADO},{APAGADO,ACESO,ACESO},
- {ACESO,APAGADO,ACESO},{APAGADO,APAGADO,APAGADO},
- {APAGADO,ACESO,APAGADO}};
- /*!
- * Inicialização do tSysTick
- */
- InitSysTick();
- /*!
- * Inicializações do GPIO do Kinetis
- */
- inicGPIO();
- inicLCD();
- initUART();
- /*! Inicizlize os buffers auxiliares de UART */
- //Ting: Inicializacao
- buffer_uart.head_receptor = 0;
- buffer_uart.head_transmissor = 0;
- buffer_uart.tail_receptor = 0;
- buffer_uart.tail_transmissor = 0;
- buffer_uart.receptor[0] = 0x00;
- //Ting: tem sentido so inicializar um campo?
- buffer_uart.transmissor[0] = 0x00;
- /*!
- * Habilita interrupção
- */
- enableNVIC();
- /*!
- * frequencia alterada para meio per?odo
- */
- temp = 2000.0;
- /*!
- * Execução da tarefa pisca-pisca sob controle
- */
- /*!
- * Maior digito sera 1 do perido 1/0.5, ent?o h? 3 caracteres
- */
- //s = (char *)malloc(10*sizeof(char));
- criaBitmapI(0x00);/*!cria o bit map*/
- //Ting: inicializar com "Cor: " e "Periodo: "
- RS(0);
- enviaLCD(0b10000000, 4); ///< posicione o cursor
- mandaString("Cor:"); ///< escreve cor:
- RS(0);
- enviaLCD(0b11000000, 4); ///< posicione o cursor
- mandaString("Per"); ///< escreve Periodo:
- enviaLCD(0x00,4);
- mandaString("odo:"); ///< escreve Periodo:
- char *cor;
- for(;;){
- // Ting: para aumentar a responsividade do sistema ...
- inicio: if (estado_pta5 || estado_pta12) {
- ConvFpraString(temp,s);
- switch (indice5){
- case 0:
- cor=&vermelho[0];
- break;
- case 1:
- cor=&branco[0];
- break;
- case 3:
- cor=&ciano[0];
- break;
- case 4:
- cor=&magenta[0];
- break;
- case 5:
- cor=&preto[0];
- break;
- case 6:
- cor=&verde[0];
- break;
- }
- i=0;
- while (i<4){
- insere_item(TRANSMISSOR, cors[i]);
- i++;
- }
- i=0;
- while (i<9){
- insere_item(TRANSMISSOR, cor[i]);
- i++;
- }
- insere_item(TRANSMISSOR, '\n');
- insere_item(TRANSMISSOR, '\r');
- i=0;
- while (i<8){
- insere_item(TRANSMISSOR, periodo[i]);
- i++;
- }
- i=0;
- while ((i<8) && (s[i]>=0x30) && (s[i]<=0x39) || (s[i]=='.')){
- insere_item(TRANSMISSOR, s[i]);
- i++;
- }
- insere_item(TRANSMISSOR, '\n');
- insere_item(TRANSMISSOR, '\r');
- estado_pta5=0;
- estado_pta12=0;
- }
- /*! Mostra a cor no LCD */
- //RS(0);
- //enviaLCD(0b10000000, 4); ///< posicione o cursor
- //RS(1);
- //mandaString(limpa); ///< limpe os campos
- //RS(0);
- //enviaLCD(0b10000000, 4); ///< posicione o cursor
- //RS(1);
- //mandaString("Cor:"); ///< escreve cor:
- RS(0);
- enviaLCD(0b10000101, 4); ///< posicione o cursor
- mostra_cor_LCD(indice5); ///< escreva o nome da cor
- //RS(0);
- //enviaLCD(0b11000000, 4); ///< posicione o cursor
- //RS(1);
- //mandaString(limpa); ///< limpe os campos
- //RS(0);
- //enviaLCD(0b11000000, 4); ///< posicione o cursor
- //RS(1);
- //mandaString("Per"); ///< escreve Periodo:
- //enviaLCD(0x00,4);
- //mandaString("odo:"); ///< escreve Periodo:
- // Ting: o seu calculo eh para unidade segundos ou ms?
- //ConvFpraString(1.0/freqs[indice12],s);
- ConvFpraString(temp,s);
- //Ting: reposicionar o cursor no campo dos valores somente
- RS(0);
- enviaLCD(0b11001000, 4); ///< posicione o cursor
- mandaString(" "); //Ting: nao precisa RS(1) porque eh chamada na rotina mandaString
- RS(0);
- enviaLCD(0b11001000, 4); ///< reposicione o cursor
- mandaString(s); ///< escreve cor:
- mandaString("ms"); ///< escreve Periodo:
- /*!
- * Exibe a cor conforme o intervalo de tempo estimado
- */
- led (VERMELHO, cores_estaticas[indice5].vermelho);
- led (VERDE, cores_estaticas[indice5].verde);
- led (AZUL, cores_estaticas[indice5].azul);
- // Ting: quando ha alteracao ... novo processamento antes do laco de espera ...
- if (estado_pta5 || estado_pta12) goto inicio;
- /*!
- * Pisca conforme o intervalo de tempo estimado
- */
- //Ting: O que acha de usar delay10us para nao repetir as contas?
- //delayfreq(freqs[indice12]); /*! Espera 1/(2*freqs[indice12]) */
- delay10us(temp*50);
- GPIOB_PSOR |= (1<<18) | (1<<19); /*! Set bit 18 e 19, LED vermelho em PTB18 e LED verde em PTB19 (apaga) */
- GPIOD_PSOR |= (1<<1); /*! Set bit 1, LED azul em PTD1(apaga) */
- // Ting: quando ha alteracao ... novo processamento antes do laco de espera ...
- if (estado_pta5 || estado_pta12) goto inicio;
- //Ting: O que acha de usar delay10us para nao repetir as contas?
- // delayfreq(freqs[indice12]);
- delay10us(temp*50);
- }
- /*!
- * Libera o espaço da memória alocada dinamicamente
- */
- // Ting : deveria ter desalocado s!!!
- //free((void *)freqs);
- return 1;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement