initial commit, first Hardwaretest works

This commit is contained in:
Luzia Christiane Tesar 2026-10-07 00:12:45 +02:00
parent 308cdb28ab
commit 2003938552
7 changed files with 674 additions and 0 deletions

23
Makefile Normal file
View File

@ -0,0 +1,23 @@
PROGRAM_NAME = mqtt_ledpanel
SRC_DIR = src
BUILD_DIR = build
all: $(PROGRAM_NAME)
# Create the build directory
$(BUILD_DIR):
mkdir -pv $(BUILD_DIR)
# Compile and build the program for Atmega328P
$(PROGRAM_NAME): $(BUILD_DIR)
avr-gcc -mmcu=atmega328p -Wall -Os -o $(BUILD_DIR)/$(PROGRAM_NAME).elf $(SRC_DIR)/$(PROGRAM_NAME).c
avr-objcopy -j .text -j .data -O ihex $(BUILD_DIR)/$(PROGRAM_NAME).elf $(BUILD_DIR)/$(PROGRAM_NAME).hex
# Upload the built program (hex file) to Atmega328P using USBasp
upload: $(PROGRAM_NAME)
avrdude -c arduino -p m328p -P /dev/ttyUSB0 -b 57600 -U flash:w:$(BUILD_DIR)/$(PROGRAM_NAME).hex -D
# Remove build directory with all built files
clean:
rm -rf $(BUILD_DIR)

Binary file not shown.

BIN
src/.mqtt_ledpanel.c.swp Normal file

Binary file not shown.

BIN
src/.si5351_rfgen.c.swp Normal file

Binary file not shown.

206
src/led_panel_example.c Normal file
View File

@ -0,0 +1,206 @@
#include <avr/io.h>
#include <util/delay.h>
#include <stdint.h>
/// ATMEGA 328p
#define ENABLE PD7
#define LATCH PB0
#define CLOCK PB1
#define ROT PD6
#define GRÜN PD5
#define BLAU PD4
void sendSPI (uint16_t SPIdata);
uint16_t count = 0;
uint16_t value ;
uint16_t SPIstring [16];
uint16_t SPIbuffer = 0;
uint16_t SPIstring_count;
uint8_t bcd [5];
//////////////////////////////////////// M A I N /////////////////////////////////////////////
int main(void)
{
DDRD = 0xF0; // PD0-3 als Eingang, PD4-7 als Ausgang setzen
DDRB = 0x0F; // PB0-3 als Ausgang, PD4-7 als Ausgang setzen
PORTD = 0x0F; // Pullup für PD0-3 aktivieren.
// Initialisierung des LED
PORTB |= (1<<LATCH); // ENABLE
count = 0;
//////////////////////MAIN Schleife ///////////////////////////
while(1)
{
_delay_ms (250); // Zyklusgeschwindigkeit von Hauptprogramm bestimmen.
count++;
value = count;
bcd[0] = value % 10; value = value/10;
bcd[1] = value % 10; value = value/10;
bcd[2] = value % 10; value = value/10;
bcd[3] = value % 10; value = value/10;
bcd[4] = value % 10;
LED_putC (bcd[3]);
LED_putC (bcd[2]);
LED_putC (bcd[1]);
LED_putC (bcd[0]);
LED_putC (bcd[3]);
LED_putC (bcd[2]);
LED_putC (bcd[1]);
LED_putC (bcd[0]);
SPIstring_count = 0;
PORTD |= (1<<ENABLE); // ENABLE
sendSPI (SPIstring [0]);
sendSPI (SPIstring [1]);
sendSPI (SPIstring [2]);
sendSPI (SPIstring [3]);
sendSPI (SPIstring [4]);
sendSPI (SPIstring [5]);
sendSPI (SPIstring [6]);
sendSPI (SPIstring [7]);
sendSPI (SPIstring [8]);
sendSPI (SPIstring [9]);
sendSPI (SPIstring [10]);
sendSPI (SPIstring [11]);
sendSPI (SPIstring [12]);
sendSPI (SPIstring [13]);
sendSPI (SPIstring [14]);
sendSPI (SPIstring [15]);
/*
setSPI (0x5552); // "0" oben
setSPI (0x2232); // "1" oben
setSPI (0x2452); // "2" oben
setSPI (0x2452); // "3" oben
setSPI (0x0255); // "0" unten
setSPI (0x0722); // "1" unten
setSPI (0x0712); // "2" unten
setSPI (0x0254); // "3" unten
setSPI (0x7554); // "4" oben
setSPI (0x3117); // "5" oben
setSPI (0x3116); // "6" oben
setSPI (0x2447); // "7" oben
setSPI (0x0444); // "4" unten
setSPI (0x0344); // "5" unten
setSPI (0x0255); // "6" unten
setSPI (0x0112); // "7" unten
setSPI (0x2552); // "8" oben
setSPI (0x5552); // "9" oben
setSPI (0x0000); // " " oben
setSPI (0x0220); // ":" oben
setSPI (0x0255); // "8" unten
setSPI (0x0346); // "9" unten
setSPI (0x0000); // " " unten
setSPI (0x0220); // ":" unten
*/
PORTD &= ~(1<<ENABLE); // ENABLE
//_delay_us (250);
//PORTD ^= (1<<ENABLE); // ENABLE
}
}
///////////////////////////////// E n d o f M A I N /////////////////////////////////////
//////////////////////////////// BCD to bitmap converting ///////////////////////////////////
void LED_putC (uint8_t putChar ){
switch (putChar){
case 0: SPIstring[SPIstring_count] = 0x5552; SPIstring[SPIstring_count+4] = 0x0255; break;
case 1: SPIstring[SPIstring_count] = 0x2232; SPIstring[SPIstring_count+4] = 0x0722; break;
case 2: SPIstring[SPIstring_count] = 0x2452; SPIstring[SPIstring_count+4] = 0x0712; break;
case 3: SPIstring[SPIstring_count] = 0x2452; SPIstring[SPIstring_count+4] = 0x0254; break;
case 4: SPIstring[SPIstring_count] = 0x7554; SPIstring[SPIstring_count+4] = 0x0444; break;
case 5: SPIstring[SPIstring_count] = 0x3117; SPIstring[SPIstring_count+4] = 0x0344; break;
case 6: SPIstring[SPIstring_count] = 0x3116; SPIstring[SPIstring_count+4] = 0x0255; break;
case 7: SPIstring[SPIstring_count] = 0x2447; SPIstring[SPIstring_count+4] = 0x0112; break;
case 8: SPIstring[SPIstring_count] = 0x2552; SPIstring[SPIstring_count+4] = 0x0255; break;
case 9: SPIstring[SPIstring_count] = 0x5552; SPIstring[SPIstring_count+4] = 0x0346; break;
}
SPIstring_count++;
if (SPIstring_count &0x04) SPIstring_count = SPIstring_count + 4;
}
///////////////////////// END of Data to bitmap converting ///////////////////////////////////
/////////////////////////////////SPI-STRING////////////////////////////////////////////
// Hier wird 16bit-Daten & Takt & /CS an SPI-PORT rausschicken & gesteuert.
void sendSPI (uint16_t SPIdata){
SPIbuffer = SPIdata ; // Daten an MAX504 anpassen, 2 bit nach links verschieben
int ii=1;
while(ii <= 16) { // 16mal wiederholen.
ii++;
PORTB &= ~(1 << PB1); // Takt fallende Flanke
_delay_us (1); // Verzögerung von 1µS
PORTD &= ~(1 << PD4); // MOSI auf LOW
PORTD &= ~(1 << PD5); // MOSI auf LOW
PORTD &= ~(1 << PD6); // MOSI auf LOW
if (SPIbuffer &0x0001) { // wenn 1, dann MOSI = H
PORTD |= (1 <<PD4) ;
PORTD |= (1 <<PD5) ;
PORTD |= (1 <<PD6) ;}
SPIbuffer = SPIbuffer >> 1 ; // Byte um 1 nach links verschieben
PORTB |= (1 <<PB1) ; // Takt steigende Flanke
_delay_us (1); // Verzögerung 1µS
}
PORTD &= ~(1 << PD4); // MOSI auf LOW
PORTD &= ~(1 << PD5); // MOSI auf LOW
PORTD &= ~(1 << PD6); // MOSI auf LOW
PORTB |= (1 <<PB0) ; // /Latch auf HIGH
_delay_us (2); // Verzögerung 1µS
PORTB &= ~(1 << PB0); // /Latch auf LOW
}
//////////////////////////////END of SPI-STRING////////////////////////////////////////////////

430
src/mqtt_ledpanel.c Normal file
View File

@ -0,0 +1,430 @@
/*****************************************************************/
/* Comb generator with Si5153 and ATMega328PB */
/* ************************************************************ */
/* Mikrocontroller: ATMEL AVR ATmega328, 8 MHz */
/* */
/* Compiler: GCC (GNU AVR C-Compiler) */
/* Author: Luzia Christiane Tesar */
/* Last Change: 2025-08-22 */
/*****************************************************************/
// This is a minimal Firmware for the SI5351 Comb Generator
// Developed 2025 at the chair of elektromagnetic theory and
// compatibility at TU Dresden
// it enables basic interpretion of some SCPI-Style commands and a manual control of the generator using a rotary switch
// The code snippet for the communication with the si5351 is a fork from DK7IH:
// https://dk7ih.de/a-simple-software-to-control-the-si5351a-generator-chip/
#define F_CPU 16000000UL
#include <inttypes.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
#include <stdint.h>
#include <avr/io.h>
#include <avr/interrupt.h>
#include <avr/sleep.h>
#include <avr/eeprom.h>
#include <util/delay.h>
#include <util/atomic.h>
#include "uart.h"
#define BAUDRATE 9600
#define TRUE 1
#define FALSE 0
#define CHAR_NEWLINE '\n'
#define CHAR_RETURN '\r'
#define RETURN_NEWLINE "\r\n"
#define CR "\r\n"
volatile unsigned char data_in[32];
unsigned char command_in[32];
volatile unsigned int data_count;
volatile unsigned char command_ready;
volatile unsigned char remote;
//volatile char cmd[32], value[32], unit[32];
unsigned long t1, freq;
#define ENABLE PD7
#define LATCH PB0
#define CLOCK PB1
#define ROT PD6
#define GRÜN PD5
#define BLAU PD4
void sendSPI (uint16_t SPIdata);
uint16_t count = 0;
uint16_t value ;
uint16_t SPIstring [16];
uint16_t SPIbuffer = 0;
uint16_t SPIstring_count;
uint8_t bcd [5];
//////////////////////////////// BCD to bitmap converting ///////////////////////////////////
void LED_putC (uint8_t putChar ){
switch (putChar){
case 0: SPIstring[SPIstring_count] = 0x5552; SPIstring[SPIstring_count+4] = 0x0255; break;
case 1: SPIstring[SPIstring_count] = 0x2232; SPIstring[SPIstring_count+4] = 0x0722; break;
case 2: SPIstring[SPIstring_count] = 0x2452; SPIstring[SPIstring_count+4] = 0x0712; break;
case 3: SPIstring[SPIstring_count] = 0x2452; SPIstring[SPIstring_count+4] = 0x0254; break;
case 4: SPIstring[SPIstring_count] = 0x7554; SPIstring[SPIstring_count+4] = 0x0444; break;
case 5: SPIstring[SPIstring_count] = 0x3117; SPIstring[SPIstring_count+4] = 0x0344; break;
case 6: SPIstring[SPIstring_count] = 0x3116; SPIstring[SPIstring_count+4] = 0x0255; break;
case 7: SPIstring[SPIstring_count] = 0x2447; SPIstring[SPIstring_count+4] = 0x0112; break;
case 8: SPIstring[SPIstring_count] = 0x2552; SPIstring[SPIstring_count+4] = 0x0255; break;
case 9: SPIstring[SPIstring_count] = 0x5552; SPIstring[SPIstring_count+4] = 0x0346; break;
}
SPIstring_count++;
if (SPIstring_count &0x04) SPIstring_count = SPIstring_count + 4;
}
///////////////////////// END of Data to bitmap converting ///////////////////////////////////
/////////////////////////////////SPI-STRING////////////////////////////////////////////
// Hier wird 16bit-Daten & Takt & /CS an SPI-PORT rausschicken & gesteuert.
void sendSPI (uint16_t SPIdata){
SPIbuffer = SPIdata ; // Daten an MAX504 anpassen, 2 bit nach links verschieben
int ii=1;
while(ii <= 16) { // 16mal wiederholen.
ii++;
PORTB &= ~(1 << PB1); // Takt fallende Flanke
_delay_us (1); // Verzögerung von 1µS
PORTD &= ~(1 << PD4); // MOSI auf LOW
PORTD &= ~(1 << PD5); // MOSI auf LOW
PORTD &= ~(1 << PD6); // MOSI auf LOW
if (SPIbuffer &0x0001) { // wenn 1, dann MOSI = H
PORTD |= (1 <<PD4) ;
PORTD |= (1 <<PD5) ;
PORTD |= (1 <<PD6) ;}
SPIbuffer = SPIbuffer >> 1 ; // Byte um 1 nach links verschieben
PORTB |= (1 <<PB1) ; // Takt steigende Flanke
_delay_us (1); // Verzögerung 1µS
}
PORTD &= ~(1 << PD4); // MOSI auf LOW
PORTD &= ~(1 << PD5); // MOSI auf LOW
PORTD &= ~(1 << PD6); // MOSI auf LOW
PORTB |= (1 <<PB0) ; // /Latch auf HIGH
_delay_us (2); // Verzögerung 1µS
PORTB &= ~(1 << PB0); // /Latch auf LOW
}
//////////////////////////////END of SPI-STRING////////////////////////////////////////////////
/////////////////////
//
// TWI-Functions
//
/////////////////////
void twi_init(void)
{
//set SCL to 400kHz
TWSR = 0x00;
TWBR = 0x0C;
//enable TWI
TWCR = (1<<TWEN);
}
//Send start signal
void twi_start(void)
{
TWCR = (1<<TWINT)|(1<<TWSTA)|(1<<TWEN);
while ((TWCR & (1<<TWINT)) == 0);
}
//send stop signal
void twi_stop(void)
{
TWCR = (1<<TWINT)|(1<<TWSTO)|(1<<TWEN);
}
void twi_write(uint8_t u8data)
{
TWDR = u8data;
TWCR = (1<<TWINT)|(1<<TWEN);
while ((TWCR & (1<<TWINT)) == 0);
}
/////////////////////////////////////////////
// M I S C
/////////////////////////////////////////////
//Substitute defective _delay_ms() function in delay.h
void wait_ms(int ms)
{
int t1, t2;
int dtime = (int) 137 * 8;
for(t1 = 0; t1 < ms; t1++)
{
for(t2 = 0; t2 < dtime; t2++)
{
asm volatile ("nop" ::);
}
}
}
/////////////////////////////////////////////
// U A R T
/////////////////////////////////////////////
void uart_init (void)
{
//uint8_t sreg = SREG;
uint16_t ubrr = (uint16_t) ((uint32_t) F_CPU/(16UL*BAUDRATE) - 1);
UBRR0H = (uint8_t) (ubrr>>8);
UBRR0L = (uint8_t) (ubrr);
// Interrupts kurz deaktivieren
cli();
// UART Receiver und Transmitter anschalten, Receive-Interrupt aktivieren
// Data mode 8N1, asynchron
UCSR0B = (1 << RXEN0) | (1 << TXEN0) | (1 << RXCIE0);
UCSR0C = (0 << 4) | (0 << 3) | (3 << 1);
// Flush Receive-Buffer (entfernen evtl. vorhandener ungültiger Werte)
do
{
// UDR auslesen (Wert wird nicht verwendet)
UDR0;
}
while (UCSR0A & (1 << RXC0));
// Rücksetzen von Receive und Transmit Complete-Flags
UCSR0A = (1 << RXC0) | (1 << TXC0);
}
int uart_putc (const uint8_t c)
{
// Warten, bis UDR bereit ist für einen neuen Wert
while (!(UCSR0A & (1 << UDRE0)))
;
// UDR Schreiben startet die Übertragung
UDR0 = c;
return 1;
}
void uart_puts (const char *s)
{
do
{
uart_putc (*s);
}
while (*s++);
}
void usart_ok()
{
uart_puts("OK\r\n");
}
void copy_command ()
{
// The USART might interrupt this - don't let that happen!
ATOMIC_BLOCK(ATOMIC_FORCEON) {
// Copy the contents of data_in into command_in
memcpy(command_in, data_in, 32);
// Now clear data_in, the USART can reuse it now
memset(data_in, 0, 32);
}
}
//void split_command(char str[]){
// str[strlen(str)-1] = '\0';
// strcpy(cmd, strtok(str , " "));
// strcpy(value, strtok(NULL, " "));
// strcpy(unit , strtok(NULL, " "));
//}
//////////////////////////////////////// M A I N /////////////////////////////////////////////
int main(void)
{
DDRD = 0xF0; // PD0-3 als Eingang, PD4-7 als Ausgang setzen
DDRB = 0x0F; // PB0-3 als Ausgang, PD4-7 als Ausgang setzen
PORTD = 0x0F; // Pullup für PD0-3 aktivieren.
// Initialisierung des LED
PORTB |= (1<<LATCH); // ENABLE
count = 0;
//////////////////////MAIN Schleife ///////////////////////////
while(1)
{
_delay_ms (250); // Zyklusgeschwindigkeit von Hauptprogramm bestimmen.
count++;
value = count;
bcd[0] = value % 10; value = value/10;
bcd[1] = value % 10; value = value/10;
bcd[2] = value % 10; value = value/10;
bcd[3] = value % 10; value = value/10;
bcd[4] = value % 10;
LED_putC (bcd[3]);
LED_putC (bcd[2]);
LED_putC (bcd[1]);
LED_putC (bcd[0]);
LED_putC (bcd[3]);
LED_putC (bcd[2]);
LED_putC (bcd[1]);
LED_putC (bcd[0]);
SPIstring_count = 0;
PORTD |= (1<<ENABLE); // ENABLE
sendSPI (SPIstring [0]);
sendSPI (SPIstring [1]);
sendSPI (SPIstring [2]);
sendSPI (SPIstring [3]);
sendSPI (SPIstring [4]);
sendSPI (SPIstring [5]);
sendSPI (SPIstring [6]);
sendSPI (SPIstring [7]);
sendSPI (SPIstring [8]);
sendSPI (SPIstring [9]);
sendSPI (SPIstring [10]);
sendSPI (SPIstring [11]);
sendSPI (SPIstring [12]);
sendSPI (SPIstring [13]);
sendSPI (SPIstring [14]);
sendSPI (SPIstring [15]);
/*
setSPI (0x5552); // "0" oben
setSPI (0x2232); // "1" oben
setSPI (0x2452); // "2" oben
setSPI (0x2452); // "3" oben
setSPI (0x0255); // "0" unten
setSPI (0x0722); // "1" unten
setSPI (0x0712); // "2" unten
setSPI (0x0254); // "3" unten
setSPI (0x7554); // "4" oben
setSPI (0x3117); // "5" oben
setSPI (0x3116); // "6" oben
setSPI (0x2447); // "7" oben
setSPI (0x0444); // "4" unten
setSPI (0x0344); // "5" unten
setSPI (0x0255); // "6" unten
setSPI (0x0112); // "7" unten
setSPI (0x2552); // "8" oben
setSPI (0x5552); // "9" oben
setSPI (0x0000); // " " oben
setSPI (0x0220); // ":" oben
setSPI (0x0255); // "8" unten
setSPI (0x0346); // "9" unten
setSPI (0x0000); // " " unten
setSPI (0x0220); // ":" unten
*/
PORTD &= ~(1<<ENABLE); // ENABLE
//_delay_us (250);
//PORTD ^= (1<<ENABLE); // ENABLE
}
}
//int main(void)
//{
// //char string[]="Hello world!!";
// uart_init();
// //uart_puts(string);
// sei();
// //PORTC = 0x30;//I²C-Bus lines: PC4=SDA, PC5=SCL
// DDRB = ( 1 << PB5 ); // PB0 an PORTB als Ausgang setzen
//
// while( 1 ) { // Endlosschleife
// if (command_ready == TRUE) {
// copy_command();
// if (strcmp(command_in, "1\r")==0) {
// PORTB |= ( 1 << PB5 ); // Toggle PB0 z.B. angeschlossene LED
// }
// if (strcmp(command_in, "0\r")==0) {
// PORTB &= ~( 1 << PB5 ); // Toggle PB0 z.B. angeschlossene LED
// uart_puts("Miau\r\n");
// }
// command_ready = FALSE;
// }
// //_delay_ms(1000); // Eine Sekunde +/-1/10000 Sekunde warten...
//
// //twi_init();
// }
//
// return 0;
//}
///////////////////////////////// E n d o f M A I N /////////////////////////////////////
ISR(USART_RX_vect)
{
// Get data from the USART in register
data_in[data_count] = UDR0;
// End of line!
if (data_in[data_count] == '\r') {
command_ready = TRUE;
uart_puts("miau\r\n");
// Reset to 0, ready to go again
data_count = 0;
} else {
data_count++;
}
}

15
src/uart.h Normal file
View File

@ -0,0 +1,15 @@
#ifndef UART_H
#define UART_H
#include <avr/io.h>
extern void uart_init (void);
extern int uart_putc (const uint8_t);
extern char uart_getc (void);
static inline void uart_flush (void)
{
while (UCSR0B & (1 << UDRIE0));
}
#endif /* UART_H */