Data hosted with ♥ by Pastebin.com - Download Raw - See Original
  1. /////////////////////////////////////////////////////////////////////////////////////////////////////
  2. // Serial e HC595 v1                                                                               //
  3. // Desenvolvido por Ronaldo R. Jr                                                                  //
  4. // 12/2015                                                                                         //
  5. // naldin.net at gmail                                                                             //
  6. // Referências:                                                                                    //
  7. // Livro Make: AVR Programming, Elliot Williams                                                    //
  8. // Web:                                                                                            //
  9. // http://extremeelectronics.co.in/avr-tutorials/using-shift-registers-with-avr-micro-avr-tutorial //
  10. /////////////////////////////////////////////////////////////////////////////////////////////////////
  11.  
  12. // ATMega328p trabalhando em 1Mhz
  13.  
  14. #include <avr/io.h>
  15. #include <util/delay.h>
  16. #include <util/setbaud.h>
  17.  
  18. #define BAUD  9600               // Setar o valor desejado
  19.  
  20. #define HC595_PORT   PORTB       // Definindo portas B
  21. #define HC595_DDR    DDRB        // Definindo direção das portas
  22.  
  23. #define HC595_DS_POS PB0         // Pino de dados (DS)
  24. #define HC595_SH_CP_POS PB1      // Pino do Clock (SH_CP)
  25. #define HC595_ST_CP_POS PB2      // Pino do Latch (ST_CP)
  26.  
  27. /*** Inicio tratamento serial ***/
  28.  
  29. // Setup da serial
  30. void iniciaUSART(void) {             // Necessario setar BAUD acima
  31.   UBRR0H = UBRRH_VALUE;              // Ja esta definido em setbaud.h
  32.   UBRR0L = UBRRL_VALUE;              // Ja esta definido em setbaud.h
  33.  
  34. // Habilita TX e RX da USART
  35.   UCSR0B = (1 << TXEN0) | (1 << RXEN0);
  36.   UCSR0C = (1 << UCSZ01) | (1 << UCSZ00);   // 8 bits de dados, 1 bit de parada
  37.  
  38.   #if USE_2X
  39.     UCSR0A |= (1 << U2X0);
  40.   #else
  41.     UCSR0A &= ~(1 << U2X0);
  42.   #endif
  43. }
  44.  
  45. void enviaByte(uint8_t dado) {
  46.   loop_until_bit_is_set(UCSR0A, UDRE0);      // Aguardar bit para enviar
  47.   UDR0 = dado;                               // Envia dado
  48. }
  49.  
  50. uint8_t recebeByte(void) {
  51.   loop_until_bit_is_set(UCSR0A, RXC0);       // Aguarda chegada de dados
  52.   return UDR0;                               // Retorna o dado em recebeByte
  53. }
  54.  
  55. void imprimeString(const char valorS[]) {    // Imprime uma palavra ou letra
  56.   uint8_t i = 0;
  57.   while (valorS[i]) {
  58.     enviaByte(valorS[i]);
  59.     i++;
  60.   }
  61. }
  62.  
  63. // Recebe na serial um numero que tenha mais de um caracter e concatena.
  64. // A serial envia apenas um caracter por vez, portanto para enviar 123 é enviado 1, depois 2, depois 3.
  65. // Esta função concatena os numeros e retona em um byte (uint8_t)
  66. uint8_t recebeNumero(void) {
  67.   char centenas = '0';
  68.   char dezenas = '0';
  69.   char unidades = '0';
  70.   char valorAtual = '0';
  71.   do {
  72.     centenas = dezenas;
  73.     dezenas = unidades;
  74.     unidades = valorAtual;
  75.     valorAtual = recebeByte();
  76.     enviaByte(valorAtual);
  77.   } while (valorAtual != '\r');   // aguarda o enter para continuar
  78.   return (100 * (centenas - '0') + 10 * (dezenas - '0') + unidades - '0');
  79. }
  80.  
  81. // Envia para serial o numero em decimal.
  82. // Para visualizar na serial um numero enviado 123 (ex.), é necessario separar cada caracter,
  83. // se for enviado o byte 123 a serial recebera o caracter { que é  o valor ascii convertido.
  84. void printByte(uint8_t byte) {           // Converte um byte em um texto decimal
  85.   enviaByte('0' + (byte / 100));         // Centenas
  86.   enviaByte('0' + ((byte / 10) % 10));   // Dezenas
  87.   enviaByte('0' + (byte % 10));          // Unidades
  88. }
  89.  
  90. /*** Fim tratamento serial ***/
  91. //=========================================================================//
  92. /*** Inicio tratamento HC595 ***/
  93.  
  94. // Setando saidas para Data(DS), Clock (SH_CP), Latch (ST_CP)
  95. void HC595Init(void) {
  96.    DDRB |= (1 << HC595_SH_CP_POS) | (1 << HC595_ST_CP_POS) | (1 << HC595_DS_POS);
  97. }
  98.  
  99. // Envia clock no SH_CP
  100. void HC595Pulse(void) {
  101.    HC595_PORT|=(1<<HC595_SH_CP_POS);    //HIGH
  102.    HC595_PORT&=(~(1<<HC595_SH_CP_POS)); //LOW
  103. }
  104.  
  105. // Envia latch no ST_CP
  106. void HC595Latch(void) {
  107.    HC595_PORT|=(1<<HC595_ST_CP_POS);    //HIGH
  108.    _delay_us(10);
  109.  
  110.    HC595_PORT&=(~(1<<HC595_ST_CP_POS)); //LOW
  111.    _delay_us(10);
  112. }
  113.  
  114. // Enviando 8 bits serialmente
  115. void HC595Write(uint8_t data) {
  116.  
  117.    // Ordenado por MSB
  118.    for(uint8_t i=0;i<8;i++)
  119.    {
  120.       if(data & 0b10000000)  // Se resultado "dados & 0b10000000" for verdadeiro (1) saida = high (1)
  121.       {
  122.          HC595_PORT |= (1 << HC595_DS_POS);
  123.       }
  124.       else                   // Se resultado "dados & 0b10000000" for (0) saida = low (0)
  125.       {
  126.          HC595_PORT &= ~(1 << HC595_DS_POS);
  127.       }
  128.  
  129.       HC595Pulse();      // Pulso de clock
  130.       data = data << 1;  // Move o bit em direção ao MSB
  131.  
  132.    }
  133.  
  134.    // envia o latch
  135.    HC595Latch();
  136. }
  137.  
  138. // Função de atraso
  139. void Wait(void) {
  140.     _delay_ms(1000);
  141.    
  142. }
  143.  
  144. int main(void) {
  145.    
  146.    uint8_t serialCaractere;
  147.    HC595Init();              // Setup da direção das portas
  148.    iniciaUSART();            // Inicializa serial
  149.    HC595Write(0xFF);         // Inicia com valor em 255 (0xFF em HEX)
  150.    imprimeString("Digite um valor entre 0 e 255\n");
  151.    
  152.    while(1)
  153.    {
  154.        serialCaractere = recebeNumero();   // Aguarda novo numero e grava em serialCaractere
  155.        printByte(serialCaractere);         // Imprime numero
  156.        imprimeString("\n");                // Nova linha
  157.        HC595Write(serialCaractere);        // Envia numero para HC595
  158.        Wait();                             // Aguarda 1s
  159.    }
  160. }