This commit is contained in:
Andreas Mieke 2018-03-18 23:43:59 +01:00
parent 4093cd295f
commit dc99dcf6e8
41 changed files with 1775 additions and 19 deletions

5
.vscode/settings.json vendored Normal file
View file

@ -0,0 +1,5 @@
{
"files.associations": {
"ne555.h": "c"
}
}

View file

@ -31,7 +31,7 @@
\usepackage{htlDT} % HTBL Diplomarbeitsstyle
\usepackage{todonotes}
%\usepackage{todonotes}
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% General Settings, like Title, Students and supporters
\title{Advanced Microcontroller Training System}
@ -112,6 +112,10 @@
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% First real page
\input{Allgemein/Allgemein}
\clearpage
\pageauthor{Mieke}
\input{Mieke/Theorie}
\clearpage
\pageauthor{Schuh}
\input{Schuh/Core-Modul}
@ -120,6 +124,10 @@
\input{Schuh/Audio}
\input{Schuh/Kosten}
\clearpage
\pageauthor{Mieke}
\input{Mieke/Software}
\clearpage
\pageauthor{Mieke}
\input{Mieke/Mieke}
@ -136,7 +144,7 @@
\listoffigures
\listoftables
\printglossary[title=Begriffsverzeichnis,toctitle=Begriffsverzeichnis]
\listoftodos[To-Dos]
%\listoftodos[To-Dos]
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%% End Document
\end{document}

View file

@ -7,16 +7,4 @@ Zur Programmierung des neuen \gls{Minimalsystem}s wurde die \gls{IDE} Keil \uVis
In den nun folgenden Kapiteln wurde dieses Tutorial, in leicht abgewandelter Form, übernommen, das Originaldokument kann unter \cite{doku:tutorial} gefunden werden.
\input{Mieke/Tutorial/Tutorial}
\input{Mieke/CMSISPacks}
\section{Missing}
Theorie:
Versionierung
Git
Nextion GUI Desiger
LaTeX
SW:
Tag der offenen Tür
Testprogramm
\input{Mieke/CMSISPacks}

BIN
Mieke/Nextion/editor.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

BIN
Mieke/Nextion/settings.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

83
Mieke/SW/MT/bma.c Normal file
View file

@ -0,0 +1,83 @@
#include "bma.h"
void init_bma(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// SCL
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &gpio);
// SDA
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
I2C_InitTypeDef i2c;
I2C_StructInit(&i2c);
i2c.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
}
void run_bma(float acc_f[3])
{
int16_t acc[3];
// Select first register address to read
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, BMA_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, 0x02);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, BMA_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
// X LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[0] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// X MSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[0] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[0] & 0x0003);
if(acc[0] & 0x0200) acc[0] |= 0xFC00;
// Y LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[1] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// Y MSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[1] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[1] & 0x0003);
if(acc[1] & 0x0200) acc[1] |= 0xFC00;
// Z LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[2] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// Z MSB
I2C_AcknowledgeConfig(I2C1, DISABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[2] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[2] & 0x0003);
if(acc[2] & 0x0200) acc[2] |= 0xFC00;
I2C_GenerateSTOP(I2C1, ENABLE);
acc_f[0] = 2.0f * ((float)acc[0]/512);
acc_f[1] = 2.0f * ((float)acc[1]/512);
acc_f[2] = 2.0f * ((float)acc[2]/512);
}
void deinit_bma(void)
{
I2C_Cmd(I2C1, DISABLE);
I2C_DeInit(I2C1);
}

18
Mieke/SW/MT/bma.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef BMA_H
#define BMA_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_i2c.h" // Keil::Device:StdPeriph Drivers:I2C
#define BMA_ADDR (uint8_t)0x70 // 0b01110000
// ---- Vendor address part
// --- User address part
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
void init_bma(void);
void run_bma(float acc_f[3]);
void deinit_bma(void);
#endif

67
Mieke/SW/MT/display.c Normal file
View file

@ -0,0 +1,67 @@
#include "display.h"
#define COLORS 8
uint8_t i = 0;
char colors[COLORS][7] = {
"RED",
"BLUE",
"GRAY",
"BLACK",
"WHITE",
"GREEN",
"BROWN",
"YELLOW"
};
void init_display(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &gpio);
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOB, &gpio);
USART_InitTypeDef usart;
USART_StructInit(&usart);
usart.USART_BaudRate = 9600;
USART_Init(USART3, &usart);
USART_ClockInitTypeDef usartclock;
USART_ClockStructInit(&usartclock);
USART_ClockInit(USART3, &usartclock);
USART_Cmd(USART3, ENABLE);
}
void run_display(void)
{
char cmd[16], *cptr;
cptr = cmd;
sprintf(cmd, "cls %s\xFF\xFF\xFF", colors[i++]);
if (i == COLORS) i = 0;
while(*cptr) {
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
USART_SendData(USART3, *cptr++);
}
}
void deinit_display(void)
{
char *cmd = "rest\xFF\xFF\xFF";
while(*cmd) {
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
USART_SendData(USART3, *cmd++);
}
while(USART_GetFlagStatus(USART3, USART_FLAG_TXE) == RESET);
USART_Cmd(USART3, DISABLE);
USART_DeInit(USART3);
}

15
Mieke/SW/MT/display.h Normal file
View file

@ -0,0 +1,15 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_usart.h" // Keil::Device:StdPeriph Drivers:USART
#include <stdio.h>
void init_display(void);
void run_display(void);
void deinit_display(void);
#endif

123
Mieke/SW/MT/eeprom.c Normal file
View file

@ -0,0 +1,123 @@
#include "eeprom.h"
volatile uint32_t *EEPROMSTick, EEPROMSTickCur;
uint8_t load_byte(uint16_t eeprom_addr)
{
uint8_t data;
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, (eeprom_addr & 0xFF00) >> 8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, (eeprom_addr & 0x00FF));
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
data = I2C_ReceiveData(I2C1);
I2C_GenerateSTOP(I2C1, ENABLE);
return data;
}
void write_byte(uint16_t eeprom_addr, uint8_t data)
{
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, (eeprom_addr & 0xFF00) >> 8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, (eeprom_addr & 0x00FF));
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, data);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
EEPROMSTickCur = *EEPROMSTick;
while((*EEPROMSTick - EEPROMSTickCur) <= 50); // 5ms write cycle, see datasheet param 17
return;
}
void init_eeprom(volatile uint32_t *SysTickCnt)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// SCL
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &gpio);
// SDA
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
I2C_InitTypeDef i2c;
I2C_StructInit(&i2c);
i2c.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
EEPROMSTick = SysTickCnt;
return;
}
void run_eeprom(uint8_t *success)
{
uint8_t set, read;
*success = 0;
set = 0xAA;
write_byte(0x0000, set);
read = load_byte(0x0000);
if (set != read) return;
set = 0xBA;
write_byte(0x0010, set);
read = load_byte(0x0010);
if (set != read) return;
set = 0xAD;
write_byte(0x0001, set);
read = load_byte(0x0001);
if (set != read) return;
set = 0x00;
write_byte(0x0000, set);
read = load_byte(0x0000);
if (set != read) return;
set = 0x88;
write_byte(0x0002, set);
read = load_byte(0x0002);
if (set != read) return;
set = 0x01;
write_byte(0x0000, set);
read = load_byte(0x0000);
if (set != read) return;
set = 0x55;
write_byte(0x00005, set);
read = load_byte(0x0005);
if (set != read) return;
set = 0xAA;
write_byte(0x0005, set);
read = load_byte(0x0005);
if (set != read) return;
*success = 1;
return;
}
void deinit_eeprom(void)
{
I2C_Cmd(I2C1, DISABLE);
I2C_DeInit(I2C1);
return;
}

18
Mieke/SW/MT/eeprom.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef EEPROM_H
#define EEPROM_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_i2c.h" // Keil::Device:StdPeriph Drivers:I2C
#define EEPROM_ADDR (uint8_t)0xA0 // 0b10100000
// ---- Vendor address part
// --- User address part
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
void init_eeprom(volatile uint32_t *SysTickCnt);
void run_eeprom(uint8_t *success);
void deinit_eeprom(void);
#endif

76
Mieke/SW/MT/esp.c Normal file
View file

@ -0,0 +1,76 @@
#include "esp.h"
void init_esp(void)
{
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOA, &gpio);
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &gpio);
USART_InitTypeDef usart;
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
USART_Init(USART2, &usart);
USART_ClockInitTypeDef usartclock;
USART_ClockStructInit(&usartclock);
USART_ClockInit(USART2, &usartclock);
NVIC_InitTypeDef nvic;
nvic.NVIC_IRQChannel = USART2_IRQn;
nvic.NVIC_IRQChannelCmd = ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority = 0;
nvic.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&nvic);
USART_ITConfig(USART2, USART_IT_RXNE, ENABLE);
USART_Cmd(USART2, ENABLE);
}
void esp_wait()
{
int i, j;
for(j=0;j<500;j++) {
for(i=0;i<65536;i++);
}
}
void send_str(char *str) {
while(*str) {
while(USART_GetFlagStatus(USART2, USART_FLAG_TXE) == RESET);
USART_SendData(USART2, *str++);
}
}
void run_esp(void)
{
send_str("AT+RESTORE\r\n");
esp_wait();
send_str("AT+CWMODE?\r\n");
esp_wait();
send_str("AT+CWMODE=2\r\n");
esp_wait();
send_str("AT+RST\r\n");
esp_wait();
send_str("AT+CIPMUX=1\r\n");
esp_wait();
send_str("AT+CIPSERVER=1,2526\r\n");
esp_wait();
send_str("AT+CIPAP_CUR?\r\n");
}
void deinit_esp(void)
{
USART_ITConfig(USART2, USART_IT_RXNE, DISABLE);
USART_Cmd(USART2, DISABLE);
USART_DeInit(USART2);
}

13
Mieke/SW/MT/esp.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef ESP_H
#define ESP_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_usart.h" // Keil::Device:StdPeriph Drivers:USART
void init_esp(void);
void run_esp(void);
void deinit_esp(void);
#endif

View file

@ -0,0 +1,139 @@
#include "interface_uart.h"
void USART_SendString(USART_TypeDef *USARTx, char *str)
{
while (*str) {
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, *str++);
}
}
void init_all(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART2, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &gpio);
gpio.GPIO_Pin = GPIO_Pin_2;
GPIO_Init(GPIOA, &gpio);
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &gpio);
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &gpio);
gpio.GPIO_Pin = GPIO_Pin_3;
GPIO_Init(GPIOA, &gpio);
gpio.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOB, &gpio);
USART_InitTypeDef usart;
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
USART_Init(USART1, &usart);
USART_Init(USART2, &usart);
USART_Init(USART3, &usart);
USART_ClockInitTypeDef usartclock;
USART_ClockStructInit(&usartclock);
USART_ClockInit(USART1, &usartclock);
USART_ClockInit(USART2, &usartclock);
USART_ClockInit(USART3, &usartclock);
USART_Cmd(USART1, ENABLE);
USART_Cmd(USART2, ENABLE);
USART_Cmd(USART3, ENABLE);
RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);
SysTick_Config(clocks.HCLK_Frequency/1000 - 1); // SysTick T=1ms
}
void send_welcome(void)
{
USART_SendString(USART1, "\x1B[2J\x1B[0;0HManufacturing test software, press space...\r\n");
USART_SendString(USART2, "\x1B[2J\x1B[0;0HManufacturing test software, press space...\r\n");
USART_SendString(USART3, "\x1B[2J\x1B[0;0HManufacturing test software, press space...\r\n");
}
unsigned int wait_for_start(void)
{
uint8_t data;
for(;;) {
if (USART_GetFlagStatus(USART1, USART_FLAG_RXNE) == SET) {
data = USART_ReceiveData(USART1);
if (data == ' ') {
USART_Cmd(USART2, DISABLE);
USART_Cmd(USART3, DISABLE);
USART_DeInit(USART2);
USART_DeInit(USART3);
return 1;
} else {
USART_Cmd(USART1, DISABLE);
USART_DeInit(USART1);
}
}
if (USART_GetFlagStatus(USART2, USART_FLAG_RXNE) == SET) {
data = USART_ReceiveData(USART2);
if (data == ' ') {
USART_Cmd(USART1, DISABLE);
USART_Cmd(USART3, DISABLE);
USART_DeInit(USART1);
USART_DeInit(USART3);
return 2;
} else {
USART_Cmd(USART2, DISABLE);
USART_DeInit(USART2);
}
}
if (USART_GetFlagStatus(USART3, USART_FLAG_RXNE) == SET) {
data = USART_ReceiveData(USART3);
if (data == ' ') {
USART_Cmd(USART1, DISABLE);
USART_Cmd(USART2, DISABLE);
USART_DeInit(USART1);
USART_DeInit(USART2);
return 3;
} else {
USART_Cmd(USART3, DISABLE);
USART_DeInit(USART3);
}
}
}
}
unsigned int wait_for_test(USART_TypeDef *USARTx)
{
int data;
for(;;)
{
if (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == SET) {
data = (int)USART_ReceiveData(USARTx);
if ((data > 0x09 && data <= 0x30) || data > 0x39) return 1;
return (data >= 0x30) ? data - 0x30 : data;
}
}
}
unsigned int get_test(USART_TypeDef *USARTx)
{
int data;
if (USART_GetFlagStatus(USARTx, USART_FLAG_RXNE) == SET) {
data = (int)USART_ReceiveData(USARTx);
if ((data > 0x09 && data <= 0x30) || data > 0x39) return 1;
return (data >= 0x30) ? data - 0x30 : data;
}
return 0;
}

View file

@ -0,0 +1,16 @@
#ifndef INTERFACE_UART_H
#define INTERFACE_UART_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_usart.h" // Keil::Device:StdPeriph Drivers:USART
void USART_SendString(USART_TypeDef *USARTx, char *str);
void init_all(void);
void send_welcome(void);
unsigned int wait_for_start(void);
unsigned int wait_for_test(USART_TypeDef *USARTx);
unsigned int get_test(USART_TypeDef *USARTx);
#endif

31
Mieke/SW/MT/ledswitch.c Normal file
View file

@ -0,0 +1,31 @@
#include "ledswitch.h"
void init_ledswitch(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Pin = GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_4 | GPIO_Pin_5 | GPIO_Pin_7 | GPIO_Pin_8 | GPIO_Pin_9;
GPIO_Init(GPIOC, &gpio);
gpio.GPIO_Mode = GPIO_Mode_IPU;
gpio.GPIO_Pin = GPIO_Pin_0 | GPIO_Pin_1 | GPIO_Pin_2 | GPIO_Pin_3 | GPIO_Pin_5 | GPIO_Pin_6 | GPIO_Pin_7 | GPIO_Pin_8;
GPIO_Init(GPIOA, &gpio);
return;
}
void run_ledswitch(uint8_t *switches)
{
*switches = (GPIO_ReadInputData(GPIOA) & 0x000F) | ((GPIO_ReadInputData(GPIOA) & 0x01E0) >> 1);
GPIO_Write(GPIOC, ((*switches & 0xE0) << 2) | ((*switches & 0x1F) << 1));
return;
}
void deinit_ledswitch(void)
{
return;
}

12
Mieke/SW/MT/ledswitch.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef LEDSWITCH_H
#define LEDSWITCH_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
void init_ledswitch(void);
void run_ledswitch(uint8_t *switches);
void deinit_ledswitch(void);
#endif

234
Mieke/SW/MT/main.c Normal file
View file

@ -0,0 +1,234 @@
#include <stdio.h>
#include "interface_uart.h"
#include "main.h"
#include "bma.h"
#include "ne555.h"
#include "ledswitch.h"
#include "eeprom.h"
#include "esp.h"
#include "rgb.h"
#include "piezo.h"
#include "display.h"
volatile uint32_t SysTickCnt = 0;
USART_TypeDef *used_usart;
void SysTick_Handler()
{
SysTickCnt++;
}
void USART2_IRQHandler()
{
USART_SendData(used_usart, USART_ReceiveData(USART2));
}
void wait(uint32_t ms)
{
uint32_t SysTickCntHold = SysTickCnt;
while((SysTickCnt - SysTickCntHold) <= ms);
}
int main()
{
char buffer[1024];
enum test_t current_test = test_not_init, next_test = test_not_init;
enum iface_t control_interface = interface_none;
for (;;) {
switch (control_interface) {
case interface_none:
init_all();
send_welcome();
control_interface = (enum iface_t)wait_for_start();
switch (control_interface) {
case interface_usart1:
used_usart = USART1;
break;
case interface_usart2:
used_usart = USART2;
break;
case interface_usart3:
used_usart = USART3;
break;
default:
control_interface = interface_none;
break;
}
break;
case interface_usart1:
case interface_usart2:
case interface_usart3:
switch(current_test) {
case test_not_init:
current_test = test_none;
break;
case test_none:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HManufacturing test software, Version " VERSION "\r\n\r\n\
\tTo run tests, enter one of the following numbers:\r\n\t\t[2]\tBMA\r\n\t\t[3]\tNE555/LFU/IR\r\n\
\t\t[4]\tLEDs and Switches\r\n\t\t[5]\tESP\r\n\t\t[6]\tEEPROM\r\n\t\t[7]\tRGB LED\r\n\t\t[8]\tPiezo\r\n\t\t[9]\tDisplay\r\n\r\nWaiting for your selection... ");
current_test = (enum test_t)wait_for_test(used_usart);
break;
case test_bma:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HBMA Test\r\n\r\nThis tests the correct function\
of the used BMA gyroscope as well as I2C port 1. Below you should see the current acceleration values printed\
for the X, Y and Z axis. Where the Z axis should show something around 1g, as this is the gravitational\
acceleration on the Earth, of course this value is lower if you run this program on the moon!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_bma();
float accs[3];
for(;;) {
run_bma(accs);
sprintf(buffer, "\x1B[K\rX: % 02.5f, Y: % 02.5f, Z: % 02.5f", accs[0], accs[1], accs[2]);
USART_SendString(used_usart, buffer);
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_bma();
break;
}
wait(50);
}
break;
case test_ne555:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HNE555/LFU/IR Test\r\n\r\nThis tests the correct function\
of the NE555/LFU/IR on the board. The currently selected frequency should be printed below!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_ne555(&SysTickCnt);
float freq;
for(;;) {
run_ne555(&freq);
sprintf(buffer, "\x1B[K\r% 05.1fHz", freq);
USART_SendString(used_usart, buffer);
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_ne555();
break;
}
wait(50);
}
break;
case test_led:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HLED/Switch Test\r\n\r\nThis tests the correct function\
of the switches and the leds on the board. The currently selected leds are shown hexadecimal below!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_ledswitch();
uint8_t switches;
for(;;) {
run_ledswitch(&switches);
sprintf(buffer, "\x1B[K\rSelected: 0x%02x", switches);
USART_SendString(used_usart, buffer);
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_ledswitch();
break;
}
wait(50);
}
break;
case test_esp:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HESP Test\r\n\r\nThis tests the correct function\
of the ESP module on the board. The ESP should open a WLAN AP!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_esp();
sprintf(buffer, "\x1B[K\rRunning test...\r\n\r\n");
USART_SendString(used_usart, buffer);
run_esp();
for(;;) {
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_esp();
break;
}
wait(50);
}
break;
case test_eeprom:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HEEPROM Test\r\n\r\nThis tests the correct function\
of the EEPROM on the board. The test will run and show an OK or NOK below!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_eeprom(&SysTickCnt);
uint8_t success;
sprintf(buffer, "\x1B[K\rRunning test...");
USART_SendString(used_usart, buffer);
run_eeprom(&success);
if(success == 1) sprintf(buffer, "OK");
else sprintf(buffer, "NOK");
USART_SendString(used_usart, buffer);
for(;;) {
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_eeprom();
break;
}
wait(50);
}
break;
case test_rgb:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HRGB LED Test\r\n\r\nThis tests the correct function\
of the RGB LED and it's I2C driver on the board!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_rgb();
for(;;) {
run_rgb();
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_rgb();
break;
}
wait(50);
}
break;
case test_piezo:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HPiezo Test\r\n\r\nThis tests the correct function\
of the Piezo on the board. You should hear the frequency printed below!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_piezo(&SysTickCnt);
for(;;) {
run_piezo();
sprintf(buffer, "\x1B[K\r500Hz");
USART_SendString(used_usart, buffer);
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_piezo();
break;
}
wait(50);
}
break;
case test_display:
USART_SendString(used_usart, "\x1B[2J\x1B[0;0HDisplay Test\r\n\r\nThis tests the correct function\
of the Display on the board. You should see text printed on the display!\r\n\r\n\
To return to the main menu press a button.\r\n\r\n\r\n");
init_display();
for(;;) {
run_display();
sprintf(buffer, "OK");
USART_SendString(used_usart, buffer);
next_test = (enum test_t)get_test(used_usart);
if (next_test != test_not_init) {
current_test = next_test;
deinit_display();
break;
}
wait(50);
}
break;
default:
current_test = test_none;
break;
}
break;
default:
break;
}
}
}

30
Mieke/SW/MT/main.h Normal file
View file

@ -0,0 +1,30 @@
#ifndef MAIN_H
#define MAIN_H
#define VERSION "0.1.0"
enum iface_t {
interface_none = 0,
interface_usart1,
interface_usart2,
interface_usart3
};
enum test_t {
test_not_init = 0,
test_none = 1,
test_bma,
test_ne555,
test_led,
test_esp,
test_eeprom,
test_rgb,
test_piezo,
test_display
};
void SysTick_Handler(void);
void USART2_IRQHandler(void);
void wait(uint32_t ms);
#endif

42
Mieke/SW/MT/ne555.c Normal file
View file

@ -0,0 +1,42 @@
#include "ne555.h"
volatile uint32_t *NE555STick, NE555STickCur;
uint8_t old_state;
void init_ne555(volatile uint32_t *SysTickCnt)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOB, &gpio);
NE555STick = SysTickCnt;
return;
}
void run_ne555(float *freq)
{
uint8_t state;
*freq = 0.0f;
NE555STickCur = *NE555STick;
while((*NE555STick - NE555STickCur) <= 1000)
{
state = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_0);
if (state != old_state)
{
(*freq)++;
old_state = state;
}
}
*freq /= 2;
return;
}
void deinit_ne555(void)
{
return;
}

12
Mieke/SW/MT/ne555.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef NE555_H
#define NE555_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
void init_ne555(volatile uint32_t *SysTickCnt);
void run_ne555(float *freq);
void deinit_ne555(void);
#endif

42
Mieke/SW/MT/piezo.c Normal file
View file

@ -0,0 +1,42 @@
#include "piezo.h"
volatile uint32_t *PiezoSTick, PiezoSTickCur, Freq;
void init_piezo(volatile uint32_t *SysTickCnt)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
gpio.GPIO_Mode = GPIO_Mode_Out_PP;
gpio.GPIO_Pin = GPIO_Pin_0;
GPIO_Init(GPIOB, &gpio);
PiezoSTick = SysTickCnt;
return;
}
void run_piezo()
{
uint8_t pstate = 0x0;
PiezoSTickCur = *PiezoSTick;
while((*PiezoSTick - PiezoSTickCur) <= 1000)
{
Freq = *PiezoSTick;
while((*PiezoSTick - Freq) <= 1);
if (pstate) {
pstate = ~pstate;
GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_SET);
} else {
pstate = ~pstate;
GPIO_WriteBit(GPIOB, GPIO_Pin_0, Bit_RESET);
}
}
return;
}
void deinit_piezo(void)
{
return;
}

12
Mieke/SW/MT/piezo.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef PIEZO_H
#define PIEZO_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
void init_piezo(volatile uint32_t *SysTickCnt);
void run_piezo(void);
void deinit_piezo(void);
#endif

89
Mieke/SW/MT/rgb.c Normal file
View file

@ -0,0 +1,89 @@
#include "rgb.h"
#include "main.h"
typedef enum {
RGB_SHUTDOWN = 0x00,
RGB_MAXCUR,
RGB_RED,
RGB_GREEN,
RGB_BLUE,
RGB_UPLEND,
RGB_DOWNLEND,
RGB_DIMSTEP
} RGB_T;
void rgb_send_command(uint8_t data)
{
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, RGB_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, data);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
return;
}
void init_rgb(void)
{
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// SCL
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &gpio);
// SDA
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
I2C_InitTypeDef i2c;
I2C_StructInit(&i2c);
i2c.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
// LED actually allows 40mA, but driver only hanbdles around 30
rgb_send_command(0x3F);
return;
}
void run_rgb(void)
{
rgb_send_command(0x5F);
wait(100);
rgb_send_command(0x7F);
wait(100);
rgb_send_command(0x9F);
wait(100);
rgb_send_command(0x50);
wait(100);
rgb_send_command(0x70);
wait(100);
rgb_send_command(0x90);
wait(100);
rgb_send_command(0x40);
wait(100);
rgb_send_command(0x60);
wait(100);
rgb_send_command(0x80);
wait(100);
return;
}
void deinit_rgb(void)
{
I2C_Cmd(I2C1, DISABLE);
I2C_DeInit(I2C1);
return;
}

18
Mieke/SW/MT/rgb.h Normal file
View file

@ -0,0 +1,18 @@
#ifndef RGB_H
#define RGB_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_i2c.h" // Keil::Device:StdPeriph Drivers:I2C
#define RGB_ADDR (uint8_t)0x70 // 0b01110000
// ---- Vendor address part
// --- User address part
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
void init_rgb(void);
void run_rgb(void);
void deinit_rgb(void);
#endif

14
Mieke/SW/ODD/bluetooth.c Normal file
View file

@ -0,0 +1,14 @@
#include "bluetooth.h"
void bluetooth_init(void)
{
usart1_init();
}
void bluetooth_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z)
{
char __str[128] = {0};
char *str = __str;
sprintf(str, "%d,%d,%d\r\n", X, Y, Z);
USART_SendString(USART1, str);
}

11
Mieke/SW/ODD/bluetooth.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef BLUETOOTH_H
#define BLUETOOTH_H
#include "stm32f10x.h" // Device header
#include "io.h"
#include "stdio.h"
void bluetooth_init(void);
void bluetooth_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z);
#endif

61
Mieke/SW/ODD/bma.c Normal file
View file

@ -0,0 +1,61 @@
#include "bma.h"
#define BMA_ADDR (uint8_t)0x70 // 0b01110000
// ---- Vendor address part
// --- User address part
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
void bma_init(void)
{
i2c1_init();
}
void bma_get_acc(uint8_t *X, uint8_t *Y, uint8_t *Z)
{
int16_t acc[3];
// Select first register address to read
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, BMA_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, 0x02);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTOP(I2C1, ENABLE);
I2C_GenerateSTART(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, BMA_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
// X LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[0] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// X MSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[0] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[0] & 0x0003);
if(acc[0] & 0x0200) acc[0] |= 0xFC00;
// Y LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[1] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// Y MSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[1] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[1] & 0x0003);
if(acc[1] & 0x0200) acc[1] |= 0xFC00;
// Z LSB
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[2] = (I2C_ReceiveData(I2C1) & 0xC0) >> 6;
// Z MSB
I2C_AcknowledgeConfig(I2C1, DISABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
acc[2] = (I2C_ReceiveData(I2C1) & 0xFF) << 2 | (acc[2] & 0x0003);
if(acc[2] & 0x0200) acc[2] |= 0xFC00;
I2C_GenerateSTOP(I2C1, ENABLE);
*X = (acc[0]/4) + 128;
*Y = (acc[1]/4) + 128;
*Z = (acc[2]/4) + 128;
}

11
Mieke/SW/ODD/bma.h Normal file
View file

@ -0,0 +1,11 @@
#ifndef BMA_H
#define BMA_H
#include "stm32f10x.h" // Device header
#include "io.h"
void bma_init(void);
void bma_get_acc(uint8_t *X, uint8_t *Y, uint8_t *Z);
#endif

59
Mieke/SW/ODD/display.c Normal file
View file

@ -0,0 +1,59 @@
#include "display.h"
disp_state_t state = DISP_STATE_NONE;
uint8_t running = 0;
void USART3_IRQHandler(void)
{
if (USART_GetITStatus(USART3, USART_IT_RXNE) == SET) {
state = (disp_state_t)((USART_ReceiveData(USART3) & 0x00FF) - '0');
if (state > 4) {
state = DISP_STATE_NONE;
}
}
if (state == DISP_STATE_START) {
running = 1;
} else if (state == DISP_STATE_PAUSE) {
running = 0;
}
}
void disp_init(void)
{
usart3_init();
NVIC_InitTypeDef nvic;
nvic.NVIC_IRQChannel = USART3_IRQn;
nvic.NVIC_IRQChannelCmd = ENABLE;
nvic.NVIC_IRQChannelPreemptionPriority = 0;
nvic.NVIC_IRQChannelSubPriority = 2;
NVIC_Init(&nvic);
USART_ITConfig(USART3, USART_IT_RXNE, ENABLE);
disp_disable();
}
disp_state_t disp_get_last_state(void)
{
disp_state_t tmp = state;
state = DISP_STATE_NONE;
return tmp;
}
void disp_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z)
{
char __str[128] = {0};
char *str = __str;
sprintf(str, "add 1,0,%d\xFF\xFF\xFF" "add 1,1,%d\xFF\xFF\xFF" "add 1,2,%d\xFF\xFF\xFF", X, Y, Z);
USART_SendString(USART3, str);
}
void disp_disable(void)
{
USART_SendString(USART3, "dim=0\xFF\xFF\xFF");
}
void disp_enable(void)
{
USART_SendString(USART3, "dim=100\xFF\xFF\xFF");
}

24
Mieke/SW/ODD/display.h Normal file
View file

@ -0,0 +1,24 @@
#ifndef DISPLAY_H
#define DISPLAY_H
#include "stm32f10x.h" // Device header
#include "io.h"
#include "stdio.h"
typedef enum uint8_t {
DISP_STATE_NONE = 0x00,
DISP_STATE_PAUSE,
DISP_STATE_START,
DISP_STATE_SAVE,
DISP_STATE_RECALL,
DISP_STATE_ERROR = 0xFF - '0'
} disp_state_t;
void disp_init(void);
disp_state_t disp_get_last_state(void);
void disp_send_gyro_data(uint8_t X, uint8_t Y, uint8_t Z);
void disp_disable(void);
void disp_enable(void);
#endif

72
Mieke/SW/ODD/eeprom.c Normal file
View file

@ -0,0 +1,72 @@
#include "eeprom.h"
extern volatile uint32_t SysTickCnt;
#define EEPROM_ADDR (uint8_t)0xA0 // 0b10100000
// ---- Vendor address part
// --- User address part
// - Keep free for R/W bit (set by I2C_Send7bitAddress())
uint32_t last_write_tick = 0;
void eeprom_init(void)
{
i2c1_init();
}
void eeprom_read(uint16_t address, uint8_t *data, uint16_t length)
{
uint16_t cur_pos;
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, (address & 0xFF00) >> 8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, (address & 0x00FF));
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_GenerateSTART(I2C1, ENABLE);
I2C_AcknowledgeConfig(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Receiver);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_RECEIVER_MODE_SELECTED));
for(cur_pos = 0; cur_pos < length; cur_pos++) {
if(cur_pos == length - 1) {
I2C_AcknowledgeConfig(I2C1, DISABLE);
}
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_RECEIVED));
data[cur_pos] = I2C_ReceiveData(I2C1);
}
I2C_GenerateSTOP(I2C1, ENABLE);
}
void eeprom_write(uint16_t address, uint8_t *data, uint16_t length)
{
uint8_t cur_page = 0;
uint16_t cur_pos = 0;
address = address & 0xFFA0;
for(cur_page = 0; cur_page <= ((length-1)/64); cur_page++) {
while((SysTickCnt - last_write_tick) <= 5);
I2C_GenerateSTART(I2C1, ENABLE);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_MODE_SELECT));
I2C_Send7bitAddress(I2C1, EEPROM_ADDR, I2C_Direction_Transmitter);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_TRANSMITTER_MODE_SELECTED));
I2C_SendData(I2C1, (address & 0xFF00) >> 8);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
I2C_SendData(I2C1, (address & 0x00FF));
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
for(; (cur_pos < length) && (cur_pos%64 <= 63); cur_pos++) {
I2C_SendData(I2C1, data[cur_pos]);
while(!I2C_CheckEvent(I2C1, I2C_EVENT_MASTER_BYTE_TRANSMITTED));
}
I2C_GenerateSTOP(I2C1, ENABLE);
address += 0x0040;
last_write_tick = SysTickCnt;
}
}

13
Mieke/SW/ODD/eeprom.h Normal file
View file

@ -0,0 +1,13 @@
#ifndef EEPROM_H
#define EEPROM_H
#include "stm32f10x.h" // Device header
#include "io.h"
#include "systick.h"
void eeprom_init(void);
void eeprom_read(uint16_t address, uint8_t *data, uint16_t length);
void eeprom_write(uint16_t address, uint8_t *data, uint16_t length);
#endif

111
Mieke/SW/ODD/io.c Normal file
View file

@ -0,0 +1,111 @@
#include "io.h"
uint8_t i2c1_inited = 0;
uint8_t usart1_inited = 0;
uint8_t usart3_inited = 0;
void i2c1_init(void)
{
if (i2c1_inited == 1) {
return;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_I2C1, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// SCL
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_6;
GPIO_Init(GPIOB, &gpio);
// SDA
gpio.GPIO_Mode = GPIO_Mode_AF_OD;
gpio.GPIO_Pin = GPIO_Pin_7;
GPIO_Init(GPIOB, &gpio);
I2C_InitTypeDef i2c;
I2C_StructInit(&i2c);
i2c.I2C_ClockSpeed = 400000;
I2C_Init(I2C1, &i2c);
I2C_Cmd(I2C1, ENABLE);
i2c1_inited = 1;
}
void usart1_init(void)
{
if (usart1_inited == 1) {
return;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA, ENABLE);
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// TxD
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_9;
GPIO_Init(GPIOA, &gpio);
// RxD
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOA, &gpio);
USART_InitTypeDef usart;
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
USART_Init(USART1, &usart);
USART_ClockInitTypeDef usartclock;
USART_ClockStructInit(&usartclock);
USART_ClockInit(USART1, &usartclock);
USART_Cmd(USART1, ENABLE);
usart1_inited = 1;
}
void usart3_init(void)
{
if (usart3_inited == 1) {
return;
}
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB, ENABLE);
RCC_APB1PeriphClockCmd(RCC_APB1Periph_USART3, ENABLE);
GPIO_InitTypeDef gpio;
GPIO_StructInit(&gpio);
// TxD
gpio.GPIO_Mode = GPIO_Mode_AF_PP;
gpio.GPIO_Pin = GPIO_Pin_10;
GPIO_Init(GPIOB, &gpio);
// RxD
gpio.GPIO_Mode = GPIO_Mode_IN_FLOATING;
gpio.GPIO_Pin = GPIO_Pin_11;
GPIO_Init(GPIOB, &gpio);
USART_InitTypeDef usart;
USART_StructInit(&usart);
usart.USART_BaudRate = 115200;
USART_Init(USART3, &usart);
USART_ClockInitTypeDef usartclock;
USART_ClockStructInit(&usartclock);
USART_ClockInit(USART3, &usartclock);
USART_Cmd(USART3, ENABLE);
usart3_inited = 1;
}
void USART_SendString(USART_TypeDef *USARTx, char *str)
{
while (*str) {
while (USART_GetFlagStatus(USARTx, USART_FLAG_TXE) == RESET);
USART_SendData(USARTx, *str++);
}
}

16
Mieke/SW/ODD/io.h Normal file
View file

@ -0,0 +1,16 @@
#ifndef IO_H
#define IO_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
#include "stm32f10x_gpio.h" // Keil::Device:StdPeriph Drivers:GPIO
#include "stm32f10x_usart.h" // Keil::Device:StdPeriph Drivers:USART
#include "stm32f10x_i2c.h" // Keil::Device:StdPeriph Drivers:I2C
void i2c1_init(void);
void usart1_init(void);
void usart3_init(void);
void USART_SendString(USART_TypeDef *USARTx, char *str);
#endif

56
Mieke/SW/ODD/main.c Normal file
View file

@ -0,0 +1,56 @@
#include "display.h"
#include "bma.h"
#include "eeprom.h"
#include "bluetooth.h"
#define BUFFER_SIZE 256
int main()
{
disp_state_t current_state = DISP_STATE_NONE;
uint8_t X, Y, Z, running = 0;
uint8_t bX[BUFFER_SIZE] = {128}, bY[BUFFER_SIZE] = {128}, bZ[BUFFER_SIZE] = {128};
uint16_t buffer_pos = 0;
disp_init();
systick_init();
bma_init();
eeprom_init();
bluetooth_init();
disp_enable();
// Main loop
for (;;) {
current_state = disp_get_last_state();
if(current_state == DISP_STATE_START) {
running = 1;
} else if(current_state == DISP_STATE_PAUSE) {
running = 0;
}
if(running == 1) {
bma_get_acc(&X, &Y, &Z);
bX[buffer_pos] = X;
bY[buffer_pos] = Y;
bZ[buffer_pos] = Z;
disp_send_gyro_data(X, Y, Z);
bluetooth_send_gyro_data(X, Y, Z);
buffer_pos++;
if(buffer_pos == BUFFER_SIZE) {
buffer_pos = 0;
}
}
if(current_state == DISP_STATE_SAVE) {
eeprom_write(0x0000, bX, BUFFER_SIZE);
eeprom_write(0x0400, bY, BUFFER_SIZE);
eeprom_write(0x0800, bZ, BUFFER_SIZE);
}
if(current_state == DISP_STATE_RECALL) {
eeprom_read(0x0000, bX, BUFFER_SIZE);
eeprom_read(0x0400, bY, BUFFER_SIZE);
eeprom_read(0x0800, bZ, BUFFER_SIZE);
for(uint16_t i = 0; i < BUFFER_SIZE; i++) {
disp_send_gyro_data(bX[i], bY[i], bZ[i]);
bluetooth_send_gyro_data(bX[i], bY[i], bZ[i]);
}
}
}
}

23
Mieke/SW/ODD/systick.c Normal file
View file

@ -0,0 +1,23 @@
#include "systick.h"
volatile uint32_t SysTickCnt;
void SysTick_Handler()
{
SysTickCnt++;
}
void systick_init(void)
{
RCC_ClocksTypeDef clocks;
RCC_GetClocksFreq(&clocks);
SysTick_Config(clocks.HCLK_Frequency/1000 - 1);
SysTickCnt = 0;
}
void Wait(uint32_t ms)
{
uint32_t SysTickCntHold = SysTickCnt;
while((SysTickCnt - SysTickCntHold) <= ms);
}

12
Mieke/SW/ODD/systick.h Normal file
View file

@ -0,0 +1,12 @@
#ifndef SYSTICK_H
#define SYSTICK_H
#include "stm32f10x.h" // Device header
#include "stm32f10x_rcc.h" // Keil::Device:StdPeriph Drivers:RCC
extern volatile uint32_t SysTickCnt;
void systick_init(void);
void Wait(uint32_t ms);
#endif

136
Mieke/Software.tex Normal file
View file

@ -0,0 +1,136 @@
\section{Software}
\label{sec:software}
Im Zuge dieser Diplomarbeit entstanden zwei größere Softwareprojekte für das \gls{ARM} Cortex-M3 \gls{Minimalsystem}.
\subsection{Tag der offenen Tür}
Für die Tage der offenen Tür der HTBL Hollabrunn im Jahr 2017/18 entstand ein Testprogramm, welches die neuen Features des Minimalsystems demonstrieren sollte. Hierzu wurde ein einfaches \gls{GUI} für das NEXTION-Display programmiert, welche die X, Y und Z Werte der Beschleunigung vom über SPI angesteuerten Gyroskop ausliest, und in Form eines Graphen anzeigt. Des weiteren wurde eine -- nicht 100\% funktinierenden -- Funktion zum Speichern des Graphen (auf dem verbauten EEPROM) programmiert.
\subsubsection{main.c}
Das Hauptprogramm in \texttt{main.c} initsialisiert alle Ports sowie den SysTick Interrupt. Die einzelnen Komponenten wurden für die Übersichtlichkeit in extra Files ausgelagert. Im Hauptprogramm ist außerdem der Main-Loop, welcher die Werte vom BMA einliest und am Display ausgibt. Der Main-Loop fragt auch Displayeingaben ab und reagiert auf diese (Start/Stopp, Speichern und Laden).
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: Hauptprogramm, label=lst:sw-odd-main]{Mieke/SW/ODD/main.c}
\subsubsection{io.h}
Dieses Headerfile enthält alle Deklarationen, welche für I/O-Aufgaben des Demoprogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: I/O Headerfile, label=lst:sw-odd-ioh]{Mieke/SW/ODD/io.h}
\subsubsection{io.c}
Dieses C-File enthält die Implementation der I/O Funktionen des Demoprogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: I/O Implementation, label=lst:sw-odd-ioc]{Mieke/SW/ODD/io.c}
\subsubsection{display.h}
Dieses Headerfile enthält alle Deklarationen, welche für das Display des Demoprogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: Display Headerfile, label=lst:sw-odd-displayh]{Mieke/SW/ODD/display.h}
\subsubsection{display.c}
Dieses C-File enthält die Implementation der Display Funktionen des Demoprogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: Display Implementation, label=lst:sw-odd-displayc]{Mieke/SW/ODD/display.c}
\subsubsection{bma.h}
Dieses Headerfile enthält alle Deklarationen, welche für das Gyroskop des Demoprogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: BMA Headerfile, label=lst:sw-odd-bmah]{Mieke/SW/ODD/bma.h}
\subsubsection{bma.c}
Dieses C-File enthält die Implementation der BMA Funktionen des Demoprogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: BMA Implementation, label=lst:sw-odd-bmac]{Mieke/SW/ODD/bma.c}
\subsubsection{eeprom.h}
Dieses Headerfile enthält alle Deklarationen, welche für das EEPROM des Demoprogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: EEPROM Headerfile, label=lst:sw-odd-eepromh]{Mieke/SW/ODD/eeprom.h}
\subsubsection{eeprom.c}
Dieses C-File enthält die Implementation der EEPROM Funktionen des Demoprogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: EEPROM Implementation, label=lst:sw-odd-eepromc]{Mieke/SW/ODD/eeprom.c}
\subsubsection{bluetooth.h}
Dieses Headerfile enthält alle Deklarationen, welche für die Bluetooth-Signalübertragung des Demoprogramms wichtig sind.
\begin{warning}
Im finalen Programm wurde das Senden der Werte über Bluetooth weggelassen, da es die Main-Loop zu sehr verlangsamte, und somit die Displayausgabe nicht mehr flüssig genug war.
\end{warning}
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: Bluetooth Headerfile, label=lst:sw-odd-bluetoothh]{Mieke/SW/ODD/bluetooth.h}
\subsubsection{bluetooth.c}
Dieses C-File enthält die Implementation der Bluetooth Funktionen des Demoprogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tag der offenen Tür: Bluetooth Implementation, label=lst:sw-odd-bluetoothc]{Mieke/SW/ODD/bluetooth.c}
\subsection{Testprogramm}
Um die im Unterricht hergestellten Einheiten des \gls{Minimalsystem}s testen zu können, musste ein Testpgrogramm geschrieben werden, welches alle verwendeten Peripherieeinheiten ansteuern kann. Dabei war es nicht das Ziel eine bestimmte Funktion zu erreichen, sondenr zu testen, ob die Busse komplett durchverbunden sind, oder ob sich irgendwo auf der Leiterkarte kalte Lötstellen oder andere Fehler befinden. Dementsprechend testen diese Tests nur ob generell eine Kommunikation mit einer Peripherieeinheit möglich ist, und nicht ob diese auch korrekt funktioniert.
\subsubsection{main.h}
Einige globale Definitionen.
\lstinputlisting[language={[ANSI]C}, caption=Tests: Hauptprogramm Headerfile, label=lst:sw-mt-mainh]{Mieke/SW/MT/main.h}
\subsubsection{main.c}
Im Hauptprogramm werden die UARTs für das anzeigen der Menüs konfiguriert, die Menüs angezeigt und auf Eingaben auf eben diese reagiert. Die einzelnen Tests wurden möglichst kompakt und modular geschrieben. Ein Test stellt dabei immer ein Interface bestehend aus Init-, Run- und DeInit-Funktion.
\lstinputlisting[language={[ANSI]C}, caption=Tests: Hauptprogramm, label=lst:sw-mt-main]{Mieke/SW/MT/main.c}
\subsubsection{interface\_uart.h}
Dieses Headerfile enthält alle Deklarationen, welche für das UART Interface des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: UART Headerfile, label=lst:sw-mt-uarth]{Mieke/SW/MT/interface_uart.h}
\subsubsection{interface\_uart.c}
Dieses C-File enthält die Implementation der UART Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: UART Implementation, label=lst:sw-mt-uartc]{Mieke/SW/MT/interface_uart.c}
\subsubsection{bma.h}
Dieses Headerfile enthält alle Deklarationen, welche für den BMA Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: BMA Headerfile, label=lst:sw-mt-bmah]{Mieke/SW/MT/bma.h}
\subsubsection{bma.c}
Dieses C-File enthält die Implementation der BMA Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: BMA Implementation, label=lst:sw-mt-bmac]{Mieke/SW/MT/bma.c}
\subsubsection{ne555.h}
Dieses Headerfile enthält alle Deklarationen, welche für den NE555 Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: NE555 Headerfile, label=lst:sw-mt-ne555h]{Mieke/SW/MT/ne555.h}
\subsubsection{ne555.c}
Dieses C-File enthält die Implementation der NE555 Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: NE555 Implementation, label=lst:sw-mt-ne555c]{Mieke/SW/MT/ne555.c}
\subsubsection{ledswitch.h}
Dieses Headerfile enthält alle Deklarationen, welche für den LED/Switch Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: LED/Switch Headerfile, label=lst:sw-mt-ledswitchh]{Mieke/SW/MT/ledswitch.h}
\subsubsection{ledswitch.c}
Dieses C-File enthält die Implementation der LED/Switch Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: LED/Switch Implementation, label=lst:sw-mt-ledswitchc]{Mieke/SW/MT/ledswitch.c}
\subsubsection{eeprom.h}
Dieses Headerfile enthält alle Deklarationen, welche für den EEPROM Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: EEPROM Headerfile, label=lst:sw-mt-eepromh]{Mieke/SW/MT/eeprom.h}
\subsubsection{eeprom.c}
Dieses C-File enthält die Implementation der EEPROM Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: EEPROM Implementation, label=lst:sw-mt-eepromc]{Mieke/SW/MT/eeprom.c}
\subsubsection{esp.h}
Dieses Headerfile enthält alle Deklarationen, welche für den ESP Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: ESP Headerfile, label=lst:sw-mt-esph]{Mieke/SW/MT/esp.h}
\subsubsection{esp.c}
Dieses C-File enthält die Implementation der ESP Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: ESP Implementation, label=lst:sw-mt-espc]{Mieke/SW/MT/esp.c}
\subsubsection{rgb.h}
Dieses Headerfile enthält alle Deklarationen, welche für den RGB LED Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: RGB LED Headerfile, label=lst:sw-mt-rgbh]{Mieke/SW/MT/rgb.h}
\subsubsection{rgb.c}
Dieses C-File enthält die Implementation der RGB LED Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: RGB LED Implementation, label=lst:sw-mt-rgbc]{Mieke/SW/MT/rgb.c}
\subsubsection{piezo.h}
Dieses Headerfile enthält alle Deklarationen, welche für den Piezo Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: Piezo Headerfile, label=lst:sw-mt-piezoh]{Mieke/SW/MT/piezo.h}
\subsubsection{piezo.c}
Dieses C-File enthält die Implementation der Piezo Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: Piezo Implementation, label=lst:sw-mt-piezoc]{Mieke/SW/MT/piezo.c}
\subsubsection{display.h}
Dieses Headerfile enthält alle Deklarationen, welche für den Display Test des Testpgrogramms wichtig sind.
\lstinputlisting[language={[ANSI]C}, caption=Tests: Display Headerfile, label=lst:sw-mt-displayh]{Mieke/SW/MT/display.h}
\subsubsection{display.c}
Dieses C-File enthält die Implementation der Display Test Funktionen des Testpgrogramms.
\lstinputlisting[language={[ANSI]C}, caption=Tests: Display Implementation, label=lst:sw-mt-displayc]{Mieke/SW/MT/display.c}

46
Mieke/Theorie.tex Normal file
View file

@ -0,0 +1,46 @@
\section{Theorie}
\label{sec:theorie}
\subsection{Versionierung}
Das Kapitel Versionierung teilt sich in zwei große Teile auf, Semantic Versioning, was die Vergabe der Versionsnummer an sich behandelt und Git, was im generellen Workflow zur Versionskontrolle benutzt wurde.
\subsubsection{Semantic Versioning}
Semantic Versioning, oder auch semantische Versionierung bezeichnet ein Verfahren zur Vergabe von Versionsnummern welches sich als sehr praktisch zum Versionieren von Softwarekomponenten herausgestellt hat. Heute benutzen sehr viele große Softwareprojekte, vor allem im Open Source Bereich, Semantic Versioning für die Versionierung von Releases.
Bei Semantic Versioning setzt sich die Versionsnummer aus drei Hauptgruppen welche aus Ziffern bestehen und durch einen Punkt getrennt sind zusammen. Jede dieser Gruppen hat eine festgelegte Bedeutung, von links nach rechts heißen die Gruppen \enquote{Major}, \enquote{Minor} und \enquote{Patch}.
Ein Produkt mit der Versionsnummer \textbf{2.5.15} hat also die Major-Version \textbf{2}, Minor-Version \textbf{5} und Patch-Level \textbf{15}.
Will man nun eine neue Version der Software (oder des Produkts) veröffentlichen, so muss man, je nach Änderung, die Versionsnummer erhöhen. Hierbei wird meist nach \fref{tab:versionierung} vorgegangen.
\tab{versionierung}{Semantic Versioning Zifferngruppen}{Zifferngruppen}{|c|p{10cm}|}{
\hline
\textbf{Gruppe} & \textbf{Bedeutung}\\
\hline
Patch & wird erhöht wenn Fehler in der Software ausgebessert werden, jedoch keine neuen Funktionen hinzugefügt werden. Binäre Bibliotheken bleiben untereinander komplett kompatibel.\\
\hline
Minor & wird erhöht wenn neue Funktinen hinzugefügt werden, nebenbei können auch Fehler ausgebessert werden, ohne eine Erhöhung des Patch Levels zu erfordern. Binäre Bibliotheken sind abwärtskompatibel, das heißt Bibliotheken mit Version \textbf{2.15.6} können anstatt Version \textbf{2.10.0} verwendet werden. Umgekehrt ist das aber nur so lange möglich, so lange mein keine erweiterten Funktionen aus der Bibliothek mit der höheren Minor-Version verwendet.\\
\hline
Major & wird erhöht wenn einerseits neue Funktionen hinzugefügt werden, allerdings gleichzeit auch alte gelöscht oder sonst irgendwie inkompatibel gemacht (Umbennenung, Änderung der Übergabeparameter) werden. Binäre Bibliotheken sind, bis auf wenige Ausnahmen, normalerweise nicht kompatibel.\\
\hline
}
Für die Softwareprodukte, welche im Rahmen dieser Diplomarbeit entstanden sind, wurde Semantic Versioning angewendet, um zukünftigen Nutzern oder Bearbeitern ein solides Fundament in Sachen Kompatibilität zu gewähren.
\subsubsection{Git}
Git ist ein dezentrales Versionskontrollsystem, welches erlaubt Zeitpunkte in der Softwareentwicklung (mit Kommentaren versehen) festzuhalten, zwischen diesen zu springen und Teile von oder komplette Änderungen rückgängig zu machen, wenn dies nötig sein sollte. Git legt hierbei für jedes Projekt ein dezentrales Repository an, welches, je nach belieben auch quasi-zentral auf einem Server liegen kann. In einem Repository kann man dann entweder alleine, oder zusammen mit einer oder mehreren Personen am selben Projekt arbeiten. Git übernimmt dabei die Versionskontrolle und in den meisten Fällen auch erfolgreich die Konflktlösung.
\subsubsubsection{Repository anlegen}
Um die Arbeit an einem Projekt beginnen zu können, muss erstmal ein leeres Git-Repository erstellt werden, dies geschieht mit dem Befehl \texttt{git init}. Dieser Befehl legt im Verzeichnis, in dem man sich gerade befindet, einen \texttt{.git}-Ordner an, in welchem Git seine internen Daten speichert.
\subsubsubsection{Der erste Commit}
Nun, da ein Repository angelgt ist, kann die eigentliche Arbeit am Projekt beginnen, so wie man das gewöhnt ist. Wenn man nun vorzeigbare Ergebnisse hat, oder seinen Fortschritt vor größeren Änderungen sichern will, muss man einen Commit erstellen, dieser bildet dann den aktuellen Zustand des Projekts (mit Dateiberechtigungen) und kompletten Inhalt ab. Wenn man später zu diesem Zustand zurückkehren will, kann man einfach auf den Commit zurückkehren. Weiters speichert Git die Änderungen von einem zum nächsten Commit in einem Diff-Format, was bedeutet, dass nicht immer die ganze Datei, sondern nur die Änderungen zur letzten Version, gespeichert werden. Dies ist für ASCII-Dateien (wie zum Beispiel auch Source-Code) sehr effizient, da nicht geänderte Zeilen nicht immer abgespeichert werden müssen.
Um nun die gemachten Änderungen in den Staging-Bereich hinzuzufügen führt man nun entweder \texttt{git add -A} (für alle Dateien und Verzeichnisse) oder \texttt{git add <file.name>} für genau eine (oder mehrere angegebene) Datei(en). Nun können entweder noch weitere Dateien hinzugefügt, Dateien wieder aus dem Staging-Bereich entfernt (\texttt{git reset HEAD <file.name>}) oder ein Commit erstellt werden. Letzteres wird mit dem Befehl \texttt{git commit} gemacht, dieser öffnet den Standard-Texteditor, in welchem man eine Nachricht (meistens die Änderungen, die man gemacht hat) eingibt. Wird der Befehl mit dem Flag \texttt{-m "Nachricht"} ausgeführt, so geht kein Editor auf und der Commit wird direkt mit der angegebenen Nachricht erstellt.
\subsubsubsection{Zurück zu einer alten Version}
Wenn man nun feststellt, dass das, was man programmiert hat nicht zielführend ist oder sich gar negativ auf das Projekt ausgewirkt hat, kann man relativ einfach wieder auf eine funktionierende Version zurück kehren. Hierzu führt man zuerst \texttt{git log} aus, was dann die IDs aller Commits und die erste Zeile der Commit-Nachricht anzeigt, hier sucht man sich nun die ID heraus, zu der man zurück kehren will, und gibt diese bei \texttt{git checkout <commitid>} ein. Nun stellt Git wieder die Version her, wie sie zum Zeitpunkt des Commits existierte.
\subsection{Nextion Editor}
\subsection{\LaTeX{}}
Zum setzen der Dokumentation und anderer aus dieser Diplomarbeit resultierenden Dokument wurde \LaTeX{} verwendet. Die Verwendung von \LaTeX{} bietet im Gegensatz zu anderer Software einige Vorteile, wie zum Beispiel die einfacher Literaturverwaltung mittels BiB\LaTeX{} und das einfache erstellen von Tabellen und ähnlichem direkt in einem handelsüblichen Texteditor. Des weiteren ist es möglich ganze Dokumente in quasi unendlich kleine Teile aufzuteilen, sodass mehrere Leute parallel an einem Gesamtdokument arbeiten können.

View file

@ -194,7 +194,7 @@ Um das Messen mit einem Oszilloskop oder anderen Messgeräten zu vereinfachen wu
\label{fig:basisplatine-masse}
\end{figure}
\subsubsection{Powerswitch STMPS2141}\todo{Quelle?}
\subsubsection{Powerswitch STMPS2141}
Um USB-Geräte zu betreiben, welche selbst keine eigene Spannungsversorgung besitzen (z.B. USB-Sticks) wurde ein Powerswitch (\fref{fig:basisplatine-power}, D3) verbaut. Dieser ermöglicht es die interne \unit{5}{\volt}-Versorgung auf die USB-Buchsen zu legen, damit diese Geräte mit Spannung versorgt werden können. Sollte das Gerät zu viel Strom verbrauchen beginnt die LED (\fref{fig:basisplatine-power}, V9) zu leuchten. Durch Jumpern der Stiftleiste (\fref{fig:basisplatine-power}, X4) an den Port-Pin PC9 kann die Versorgung von externen Geräten gesteuert werden.
\begin{figure}[htb]
@ -334,7 +334,7 @@ Um die Platine auch mit einer Fernbedienung oder einem Mobiltelefon steuern zu k
\end{figure}
\subsubsection{Temperatursensor}
Um die Umgebungstemperatur feststellen zu können wurde auf der Basisplatine der Temperaturfühler DS18B20 verbaut, welcher mit Hilfe des 1-Wire Protokolls angesprochen werden kann. Die maximale Mesfehler dieses Temperatursensors beträgt ±0,5°C laut Datenblattangabe\todo{Quelle?}. Um den Temperaturfühler verwenden zu können muss lediglich der Pin9 mit dem Pin10, der Stiftleiste (\fref{fig:basisplatine-ssel}, X9), gejumpert werden.
Um die Umgebungstemperatur feststellen zu können wurde auf der Basisplatine der Temperaturfühler DS18B20 verbaut, welcher mit Hilfe des 1-Wire Protokolls angesprochen werden kann. Die maximale Mesfehler dieses Temperatursensors beträgt ±0,5°C laut Datenblattangabe. Um den Temperaturfühler verwenden zu können muss lediglich der Pin9 mit dem Pin10, der Stiftleiste (\fref{fig:basisplatine-ssel}, X9), gejumpert werden.
\begin{figure}[htb]
\centering
@ -345,7 +345,7 @@ Um die Umgebungstemperatur feststellen zu können wurde auf der Basisplatine der
\end{figure}
\subsubsection{Lichtwandler LFU}
Der auf der \gls{Basisplatine} realisierte LFU (Licht-Frequenz-Wandler), wandeltet wie der Name bereits sagt Licht in eine bestimmte Frequenz um. Je höher die Bestrahlungsstärke des Lichts, desto höher wird die über den Output des LFUs ausgegebene Frequenz. Den linearen Zusammenhang zwischen der Bestrahlungsstärke und der ausgegebenen Frequenz kann aus \fref{fig:basisplatine-lfu-freq} entnommen werden.\todo{Quelle?} Um den LFU verwenden zu können muss lediglich der Pin5 mit dem Pin6, der Stiftleiste (\fref{fig:basisplatine-ssel}, X9), gejumpert werden.
Der auf der \gls{Basisplatine} realisierte LFU (Licht-Frequenz-Wandler), wandeltet wie der Name bereits sagt Licht in eine bestimmte Frequenz um. Je höher die Bestrahlungsstärke des Lichts, desto höher wird die über den Output des LFUs ausgegebene Frequenz. Den linearen Zusammenhang zwischen der Bestrahlungsstärke und der ausgegebenen Frequenz kann aus \fref{fig:basisplatine-lfu-freq} entnommen werden. Um den LFU verwenden zu können muss lediglich der Pin5 mit dem Pin6, der Stiftleiste (\fref{fig:basisplatine-ssel}, X9), gejumpert werden.
\begin{figure}[htb]
\centering
@ -357,7 +357,7 @@ Der auf der \gls{Basisplatine} realisierte LFU (Licht-Frequenz-Wandler), wandelt
\fig{basisplatine-lfu-freq}{Frequenzgang des LFUs}{Frequenzgang des LFUs}{0.5\textwidth}{Schuh/Pictures/Basis-lfu-freq}
\subsubsection{RGB-LED}
Auf der Hardware der \gls{Basisplatine} wurde eine RGB-LED \cite{basis:rgbled} verbaut, welche mit Hilfe des LED-Divers (\fref{fig:basisplatine-rgbled}, D4) \cite{basis:rgbdriver}, welcher mit dem \IIC{}-Bus angesteuert werden kann. Dieser LED-Driver hat den Vorteil, dass er eine interne Stromüberwachung besitzt. Dadurch benötigen die einzelnen Anoden der RGB-LED keine Vorwiderstände, da sich der Strom automatisch entsprechend der gewünschten Farbe reguliert.
Auf der Hardware der \gls{Basisplatine} wurde eine RGB-LED \cite{basis:rgbled} verbaut, welche mit Hilfe des LED-Drivers (\fref{fig:basisplatine-rgbled}, D4) \cite{basis:rgbdriver}, welcher mit dem \IIC{}-Bus angesteuert werden kann. Dieser LED-Driver hat den Vorteil, dass er eine interne Stromüberwachung besitzt. Dadurch benötigen die einzelnen Anoden der RGB-LED keine Vorwiderstände, da sich der Strom automatisch entsprechend der gewünschten Farbe reguliert.
\begin{figure}[htb]
\centering