Die Mocca Demo, welche als Grundlage für Mocha-Projekte genutzt werden kann.
Mocca_Demo.c
/*********************************************************************** * * DATE : 11.11.2014 * DESCRIPTION : Testsoftware für Mocca * Author: : Christian Marty * ***********************************************************************/ #include#include #include "Mocca_Treiber.h" int main(void) { init_mocca(); init_lcd(); init_ADC(); init_rs232(103); // 103 => 9600 baud init_usb(); wait_5ms(100); init_RGB(); rs232_sende_string("Mocca RS232 gestartet"); USB_sende_string("Mocca an USB gestartet"); while(1) { rs232_sende_string("Mocca RS232"); USB_sende_string("Mocca an USB"); PORTA ++; wait_5ms(PINK); lcd_light(read_ADC(0)/100); if((PINE &0xF0)>0) { PWM_RGB(0,0,0); if((PINE&0x10) >0)RGB_Rot(1023); if((PINE&0x20) >0)RGB_Gruen(1023); if((PINE&0x40) >0)RGB_Blau(1023); if((PINE&0x80) >0)PWM_RGB(1023,1023,1023); } else PWM_RGB(read_ADC(3),read_ADC(2),read_ADC(1)); } }
Mocca_Treiber.h
/*********************************************************************** * * DATE : 28.11.2014 * DESCRIPTION : Treiber für Mocca * Author: : Christian Marty * Version : 1.1 * ***********************************************************************/ #ifndef mocca_define #define mocca_define #include#include #define FALSE 0 #define TRUE !0 void init_sirius(void); void init_mocca(void); void init_5ms_timer(void); void wait_5ms(uint16_t faktor); void wait_1us(uint16_t volatile faktor); void init_rs232 (uint16_t baudratenregister); void rs232_sende_zeichen(char zeichen); void rs232_sende_string(char *Text); void init_usb(void); void USB_sende_zeichen(char zeichen); void USB_sende_string(char *Text); void init_ADC(void); uint16_t read_ADC(uint8_t kanal); void init_RGB(void); void PWM_RGB(uint16_t Rot,uint16_t Gruen,uint16_t Blau); void RGB_Rot(uint16_t Rot); void RGB_Gruen(uint16_t Gruen); void RGB_Blau(uint16_t Blau); void init_lcd(void); void lcd_light(uint8_t hellighkeit); void lcd_on_off(uint8_t status); void write_text(uint8_t y_pos, uint8_t x_pos, char *str_ptr); void write_zahl(uint8_t x_pos, uint8_t y_pos, uint16_t zahl_v, uint8_t s_vk, uint8_t s_nk, uint8_t komma); void clear_lcd_f(void); #endif
Mocca_Treiber.c
/*********************************************************************** * * Date : 19.08.2015 / 28.11.2014 * Description : Treiber für Mocca * Author : Christian Marty / Ke * Version : 1.2 * * 2015.08. LCD-Modul Pin16 neu an 3.3V Ruhepegel (int.Pullup 10k) * init_mocca() * lcd_on_off() * clear_lcd_f() * ***********************************************************************/ #include#include "Mocca_Treiber.h" void lcd_sid(uint8_t status); void lcd_sclk(uint8_t status); void write_lcd_f(uint16_t rs, uint16_t value); volatile uint16_t takt_5ms_zaehler; //-------------------------------------------------------------------------------------------- // Initialisirung SiriusBlack //-------------------------------------------------------------------------------------------- void init_sirius(void) { init_mocca(); } void init_mocca(void) { DDRA = 0xFF; // LED Port als Ausgang DDRK = 0x00; // Schalter Port als Eingang DDRE = 0x00; // Taster als Eingang DDRG = 0x23; // LCD port als Ausgang // 2015.08 DDRH = 0x78; // RGB, CTS als Ausgang init_5ms_timer(); sei(); // Global interrups aktivieren init_lcd(); lcd_light(2); } //-------------------------------------------------------------------------------------------- // Timer 0 initialisirung //-------------------------------------------------------------------------------------------- void init_5ms_timer(void) { TCCR0A = 0b00000011; // Timer mode einstellungen -> Fast PWM mode TCCR0B = 0b00001101; // 16Mhz / 1024 = 15,635kHz TIMSK0 = 0b00000001; // Timer overflow Interrupt aktivieren OCR0A = 77; } //-------------------------------------------------------------------------------------------- // Timer 0 Overflow Interrupt -> Wird alle 5ms aufgerufen //-------------------------------------------------------------------------------------------- ISR(TIMER0_OVF_vect) { takt_5ms_zaehler --; } //-------------------------------------------------------------------------------------------- // 5ms Wartefunktion //-------------------------------------------------------------------------------------------- void wait_5ms(uint16_t faktor) { takt_5ms_zaehler = faktor; if(faktor != 0) while(takt_5ms_zaehler); } //-------------------------------------------------------------------------------------------- // 1us Wartefunktion //-------------------------------------------------------------------------------------------- void wait_1us(uint16_t volatile faktor) { while (faktor) { // 11 Taktzüklen keine operation , retliche 5 taktzyklen für while und faktor increment asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); asm ("nop"); faktor --; } } //************************** RS232 / USB -Treiber ******************************************// //-------------------------------------------------------------------------------------------- // RS232 Initialisiren //-------------------------------------------------------------------------------------------- void init_rs232 (uint16_t baudratenregister) { UCSR2B = 0b00011000; // RX und TX enable UCSR2C = 0b00000110; // Asynkrone USART, 8 Datenbits UBRR2H = (baudratenregister >>8); UBRR2L = (baudratenregister & 0x00FF); } //-------------------------------------------------------------------------------------------- // Ein einzelnes zeichen über RS232 Senden //-------------------------------------------------------------------------------------------- void rs232_sende_zeichen(char zeichen) { UDR2 = zeichen; while( (UCSR2A & 0b01000000) == 0); // Warten bis Byte gesendet UCSR2A |= 0b01000000; //Byte gesendet Flagge löschen } //-------------------------------------------------------------------------------------------- // Einen Nullterminierten string über RS232 senden //-------------------------------------------------------------------------------------------- void rs232_sende_string(char *Text) { uint8_t i = 0; while(Text[i]) { rs232_sende_zeichen(Text[i]); i++; } } //-------------------------------------------------------------------------------------------- // USB Initialisiren //-------------------------------------------------------------------------------------------- void init_usb(void) { UCSR0B = 0b00011000; // RX und TX enable UCSR0C = 0b00000110; // Asynkrone USART, 8 Datenbits // 9600 Baud UBRR0H = 0; UBRR0L = 103; } //-------------------------------------------------------------------------------------------- // Ein einzelnes zeichen über USB Senden //-------------------------------------------------------------------------------------------- void USB_sende_zeichen(char zeichen) { UDR0 = zeichen; while( (UCSR0A & 0b01000000) == 0); // Warten bis Byte gesendet UCSR0A |= 0b01000000; //Byte gesendet Flagge löschen } //-------------------------------------------------------------------------------------------- // Einen Nullterminierten string über USB senden //-------------------------------------------------------------------------------------------- void USB_sende_string(char *Text) { uint8_t i = 0; while(Text[i]) { USB_sende_zeichen(Text[i]); i++; } } //************************** A/D_Wandler-Treiber *******************************************// void init_ADC(void) { ADMUX = 0x40; //AVCC Als referenz DIDR0 = 0x0F; // Digitale Register an ADC pins der Potentiometer deaktivieren ADCSRA = 0b10100111; // ADC einschalten, ADC clok = 16MHz / 128 ADCSRB = 0x00; // Free runing mode ADCSRA |= 0b01000000; // Dummy messung Starten while((ADCSRA&0x10) == 0); // Warten bis Messung abgeschllossen ADCSRA &= 0xEF; // Interruptflage löschen } uint16_t read_ADC(uint8_t kanal) { uint16_t messwert = 0; // Kanal definieren ADMUX = 0x40; //AVCC Als referenz ADMUX |= kanal; ADCSRA |= 0b01000000; // ADC Starten while((ADCSRA&0x10) == 0); // Warten bis Messung abgeschllossen wait_5ms(1); messwert = ADCL; messwert |= ADCH <<8; ADCSRA &= 0xEF; // Interruptflage löschen return messwert; } //************************** RGB-LED-Treiber ***********************************************// //-------------------------------------------------------------------------------------------- // Initialisirung des PWM der RGB-LED //-------------------------------------------------------------------------------------------- void init_RGB(void) { uint16_t aufloesung = 1023; // 10bit pwm aufösung TCCR4A = 0b11111110; // Ausgänge als PWM Ausgang ,Fast PWM mode TCCR4B = 0b00011011; // Clock / 64 ICR4H = (aufloesung >>8); ICR4L = (aufloesung & 0x00FF); } //-------------------------------------------------------------------------------------------- // Übergabe von werten an die PWM Register //-------------------------------------------------------------------------------------------- void PWM_RGB(uint16_t Rot,uint16_t Gruen,uint16_t Blau) { Rot = 1023 - Rot; Gruen = 1023 - Gruen; Blau = 1023 - Blau; OCR4AH = (Rot >>8); OCR4AL = (Rot & 0x00FF); OCR4BH = (Gruen >>8); OCR4BL = (Gruen & 0x00FF); OCR4CH = (Blau >>8); OCR4CL = (Blau & 0x00FF); } void RGB_Rot(uint16_t Rot) { // Wenn PWM nicht inizialisirt ist Pin mit LED High oder Low setztzen if(Rot) PORTH |= 0x08; else PORTH &= 0xF7; // Wenn PWM initialisirt ist wert an PWM register übergeben Rot = 1023 - Rot; OCR4AH = (Rot >>8); OCR4AL = (Rot & 0x00FF); } void RGB_Gruen(uint16_t Gruen) { // Wenn PWM nicht inizialisirt ist Pin mit LED High oder Low setztzen if(Gruen) PORTH |= 0x10; else PORTH &= 0xEF; // Wenn PWM initialisirt ist wert an PWM register übergeben Gruen = 1023 - Gruen; OCR4BH = (Gruen >>8); OCR4BL = (Gruen & 0x00FF); } void RGB_Blau(uint16_t Blau) { // Wenn PWM nicht inizialisirt ist Pin mit LED High oder Low setztzen if(Blau) PORTH |= 0x20; else PORTH &= 0xDF; // Wenn PWM initialisirt ist wert an PWM register übergeben Blau = 1023 - Blau; OCR4CH = (Blau >>8); OCR4CL = (Blau & 0x00FF); } //************************** LCD-Treiber ***************************************************// //-------------------------------------------------------------------------------------------- // Ansteuerung von einzelen Bits fur LCD //-------------------------------------------------------------------------------------------- void lcd_sid(uint8_t status) // LCD Datenleitung { if(status) PORTG |= 0x01; else PORTG &= 0xFE; } void lcd_sclk(uint8_t status) // LCD Taktleitung { if(status) PORTG |= 0x02; else PORTG &= 0xFD; } void lcd_on_off(uint8_t status) //LCD Hardware-Reset / Ein/Aus / 2015.08 / Ke { // 2015.08 : Auch wenn dieser Codeabschnitt etwas seltsam erscheint, // ist es wichtig, dass dieser so belassen wird, Chr. Marty. if (status) { PORTG &= 0xFB; // tri state --> LCD-pullup provides 3.3V to reset pin DDRG &= 0xFB; } else { PORTG &= 0xFB; // forced low --> LCD-reset DDRG |= 0x04; } } //-------------------------------------------------------------------------------------------- // LCD Hintergundbeleuchtung mit PWM dimmen (0 bis 100%) Timer 0 muss initialisiert sein! //-------------------------------------------------------------------------------------------- void lcd_light(uint8_t hellighkeit) // Werte von 0 bis 10 möglich -> 0 = Aus , 1= 10%, 10 = 100% { if(hellighkeit == 0) { TCCR0A &= 0b11011111; //Wenn heligkeit 0 -> Hintergrundbeleuchtung ausschalten } else { TCCR0A |= 0b00100000; if(hellighkeit >10)hellighkeit = 10; OCR0B = (hellighkeit*8);// + 178; } } //-------------------------------------------------------------------------------------------- // Initialisierung des LCDs //-------------------------------------------------------------------------------------------- void init_lcd(void) { lcd_sclk(1); lcd_sid(0); lcd_on_off(0); // LCD-reset 10 ms low pulse wait_5ms(2); lcd_on_off(1); // LCD-reset back to 3.3V wait_5ms(10); write_lcd_f('C',0x34); // set 8-Bit-Interface RE = 1 write_lcd_f('C',0x09); // 4-Zeilen-Modus, 5-Dot Font-Breite write_lcd_f('C',0x30); // set 8-Bit-Interface RE = 0 write_lcd_f('C',0x0C); // Display ON, Cursor OFF clear_lcd_f(); // Clear Display write_lcd_f('C',0x07); // Entry Mode write_text(0,0, " Mocca"); write_text(1,0, " -----"); write_text(2,0, "Demo Firmware V.1.2"); write_text(3,0, " C. Marty 2014/15"); } //-------------------------------------------------------------------------------------------- // Schreibt ein Kommando oder ein Datenbyte (Zeichen) zum LCD SPI (Serial Protokoll Interface) //-------------------------------------------------------------------------------------------- void write_lcd_f(uint16_t rs, uint16_t value) { uint16_t i; // Manche Befehle müssen doppelt ausgeführt werden, damit die // minimale Pulslänge von 400ns eingehalten wird. (bei 20MHz) // Synchronisierung: 5x "1" senden lcd_sid(1); // Daten-Bit = 1 for(i=0;i<5; i++) { lcd_sclk(0); // Synch-Bits senden lcd_sclk(1); } // R/W: 1=Read, 0=Write lcd_sid(0); // R/W = 0 lcd_sclk(0); // R/W-Bit senden lcd_sclk(1); // RS Register Selection: 0=Command, 1=Data if (rs == 'C') lcd_sid(0); else lcd_sid(1); lcd_sclk(0); // RS-Bit senden lcd_sclk(1); // End-Marke 0 lcd_sid(0); lcd_sclk(0); // END-Bit senden lcd_sclk(1); // Daten-Bit 0-3 for(i=0;i<4; i++) { lcd_sclk(0); if (value & 0x01) lcd_sid(1); else lcd_sid(0); value = value >> 1; lcd_sclk(0); lcd_sclk(1); } lcd_sid(0); // 4x "0" senden for(i=0;i<4; i++) { lcd_sclk(0); lcd_sclk(1); } // Daten-Bit 4-7 for(i=0;i<4; i++) { lcd_sclk(0); if (value & 0x01) lcd_sid(1); else lcd_sid(0); value = value >> 1; lcd_sclk(0); lcd_sclk(1); } lcd_sid(0); // 4x "0" senden for(i=0;i<4; i++) { lcd_sclk(0); lcd_sclk(1); } lcd_sid(1); // Write-Befehl auf 50us verlängern, damit minimale Execution-Time 39us/43us eingehalten ist. wait_1us(50); } //------------------------------------------------------------ // Text an xy-Position ausgeben //------------------------------------------------------------ void write_text(uint8_t y_pos, uint8_t x_pos, char *str_ptr) { uint8_t str_p = 0; uint8_t pos; pos = x_pos + (y_pos * 0x20); write_lcd_f('C',pos | 0x80); while(str_ptr[str_p]) { write_lcd_f('D',str_ptr[str_p++]); } } //------------------------------------------------------------ // Zahl an xy-Position ausgeben dezimal //------------------------------------------------------------ void write_zahl(uint8_t x_pos, uint8_t y_pos, uint16_t zahl_v, uint8_t s_vk, uint8_t s_nk, uint8_t komma) { unsigned long zehner = 10; unsigned char send_buffer[12]; unsigned char i, pos, pos_t; // Umwandlung in die einzelnen Stellen-Zahlen 1er, 10er, 100er, ... // zahl = 12345; // s_vk = 2; // s_nk = 0; // komma = 0; send_buffer[11] = (zahl_v % 10) + 48; i = 10; do { send_buffer[i] = (zahl_v / zehner % 10) + 48; zehner *= 10; }while(i--); // Vor-Kommastellen kopieren pos = 0; pos_t = 12-komma-s_vk; for (i=0; i 0) { send_buffer[pos++] = '.'; // Nach-Kommastellen kopieren pos_t = 12-komma; for (i=0; i