Created
October 13, 2014 00:17
-
-
Save Mooophy/c94a703c1709537fb9e4 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
***************************************************************************** | |
* @file main.c | |
* @author Yue Wang 12027710 | |
* @version V1.0.0 | |
* @date 22-May-2013 | |
* @brief For the Assignment 5, 159.270 Hardware Oriented Programming. | |
**************************************************************************** | |
*/ | |
/* Includes ------------------------------------------------------------------*/ | |
#include "stm32f10x.h" | |
#include "stm32f10x_rcc.h" | |
#include "stm32f10x_gpio.h" | |
#include "stm32f10x_usart.h" | |
#include "stm32f10x_tim.h" | |
#include "misc.h" | |
/* Macro -------------------------------------------------------------------*/ | |
#define PWM_width uint32_t | |
#define Command char | |
#define QUEUE_SIZE 64 | |
/** | |
* @brief enumeration for degrees. | |
*/ | |
typedef enum | |
{ | |
wy_PWM_0_DeGREE = 1000, | |
wy_PWM_10_DeGREE = 1111, | |
wy_PWM_20_DeGREE = 1222, | |
wy_PWM_30_DeGREE = 1333, | |
wy_PWM_40_DeGREE = 1444, | |
wy_PWM_45_DeGREE = 1500, | |
wy_PWM_50_DeGREE = 1556, | |
wy_PWM_60_DeGREE = 1667, | |
wy_PWM_70_DeGREE = 1778, | |
wy_PWM_80_DeGREE = 1889, | |
wy_PWM_90_DeGREE = 2000, | |
} wy_PWM_WiDTH_TypeDef ; | |
/** | |
* @brief buffer for UART. | |
*/ | |
typedef struct Queue | |
{ | |
char a[QUEUE_SIZE]; | |
int start; | |
int end; | |
} Queue; | |
/** | |
* @brief Global variables. | |
*/ | |
Queue RXQ, TXQ; | |
/* Prototype------------------------------------------------------------------*/ | |
void wy_PWM_handle (wy_PWM_WiDTH_TypeDef _w); | |
void wy_Initialize (void); | |
void wy_WindScreen (void); | |
void wy_CommandHandle(Command _c); | |
void uart_putchar (char c); | |
int is_uart_data_ready(void); | |
char uart_getchar (void); | |
void delay_millisec (register unsigned short n); | |
/* Main ------------------------------------------------------------------*/ | |
int main(void) | |
{ | |
wy_Initialize(); | |
while (1) | |
{ | |
if (is_uart_data_ready()) | |
{ | |
Command c = uart_getchar(); | |
wy_CommandHandle(c); | |
uart_putchar(c); | |
} | |
} | |
} | |
/* Function definitions ------------------------------------------------------*/ | |
/** | |
* @brief USART handler. | |
*/ | |
void USART1_IRQHandler(void) | |
{ | |
//was it a receive interrupt? | |
if (USART_GetITStatus(USART1, USART_IT_RXNE) != RESET) | |
{ | |
char c = (USART1->DR & 0xff); | |
if ((RXQ.end+1)%QUEUE_SIZE != RXQ.start) | |
{ | |
RXQ.a[RXQ.end] = c; | |
RXQ.end = (RXQ.end + 1)%QUEUE_SIZE; | |
} | |
} | |
//was it a transmit interrupt? | |
if (USART_GetITStatus(USART1, USART_IT_TXE) != RESET) | |
{ | |
if (TXQ.start != TXQ.end) | |
{ | |
USART1->DR = TXQ.a[TXQ.start]; | |
TXQ.start = (TXQ.start + 1)%QUEUE_SIZE; | |
} | |
else | |
{ | |
USART1->CR1 &= ~USART_CR1_TXEIE; //disable interrupt | |
} | |
} | |
} | |
/** | |
* @brief Initialization for everything to be used. | |
*/ | |
void wy_Initialize(void) | |
{ | |
/*RCC */ | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA , ENABLE); | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB , ENABLE); | |
RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1, ENABLE); | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM4 , ENABLE); | |
RCC_APB1PeriphClockCmd(RCC_APB1Periph_TIM6 , ENABLE); | |
/*GPIO*/ | |
GPIO_InitTypeDef GPIO_InitStructure; | |
GPIO_StructInit(&GPIO_InitStructure); | |
/*PWM */ | |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_8; | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; | |
GPIO_Init(GPIOB, &GPIO_InitStructure); | |
/*RXD */ | |
GPIO_InitStructure.GPIO_Speed = GPIO_Speed_2MHz; | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_9; //PA9 <--->RXD blue | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_AF_PP; | |
GPIO_Init(GPIOA, &GPIO_InitStructure); | |
/*TXD */ | |
GPIO_InitStructure.GPIO_Pin = GPIO_Pin_10; //PA10 <--->TXD green | |
GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IN_FLOATING; | |
GPIO_Init(GPIOA, &GPIO_InitStructure); | |
/*USART*/ | |
USART_InitTypeDef USART_InitStructure; | |
USART_StructInit(&USART_InitStructure); | |
USART_InitStructure.USART_BaudRate = 9600; | |
USART_InitStructure.USART_Mode = USART_Mode_Rx | USART_Mode_Tx; | |
USART_Init(USART1, &USART_InitStructure); | |
USART_Cmd(USART1, ENABLE); | |
USART1->CR1 |= USART_CR1_RXNEIE; //enable Received data interrupt | |
/*NVIC*/ | |
NVIC_InitTypeDef NVIC_InitStructure; | |
NVIC_InitStructure.NVIC_IRQChannel = USART1_IRQn; | |
NVIC_InitStructure.NVIC_IRQChannelSubPriority = 3; | |
NVIC_InitStructure.NVIC_IRQChannelPreemptionPriority = 0; | |
NVIC_InitStructure.NVIC_IRQChannelCmd = ENABLE; | |
NVIC_Init(&NVIC_InitStructure); | |
/*TIM4*/ | |
TIM_TimeBaseInitTypeDef TIM_TimeBaseStructure; | |
TIM_TimeBaseStructInit(&TIM_TimeBaseStructure); | |
TIM_TimeBaseStructure.TIM_Prescaler = 24 - 1; | |
TIM_TimeBaseStructure.TIM_Period = 20000 - 1; | |
TIM_TimeBaseStructure.TIM_CounterMode = TIM_CounterMode_Up; | |
TIM_TimeBaseInit(TIM4, &TIM_TimeBaseStructure); | |
/*CH3*/ | |
TIM_OCInitTypeDef TIM_OCStructure; | |
TIM_OCStructInit(&TIM_OCStructure); | |
TIM_OCStructure.TIM_OCMode = TIM_OCMode_PWM1; | |
TIM_OCStructure.TIM_OutputState = TIM_OutputState_Enable; | |
TIM_OC3Init(TIM4, &TIM_OCStructure); | |
TIM_Cmd(TIM4, ENABLE); | |
} | |
/** | |
* @brief output to PUTTY. | |
*/ | |
void uart_putchar(char c) | |
{ | |
if ((TXQ.end+1)%QUEUE_SIZE != TXQ.start) | |
{ | |
TXQ.a[TXQ.end] = c; | |
TXQ.end = (TXQ.end + 1)%QUEUE_SIZE; | |
} | |
if (! (USART1->CR1&USART_CR1_TXEIE)) | |
{ //ie the tx buffer is empty | |
USART1->CR1 |= USART_CR1_TXEIE; //enable transmit interrupt | |
} | |
} | |
/** | |
* @brief check if new data have arrived. | |
*/ | |
int is_uart_data_ready(void) | |
{ | |
return (RXQ.start != RXQ.end); | |
} | |
/** | |
* @brief collect new character, write into c and return it. | |
*/ | |
char uart_getchar(void) | |
{ | |
char c = RXQ.a[RXQ.start]; | |
RXQ.start = (RXQ.start + 1)%QUEUE_SIZE; | |
return c; | |
} | |
/** | |
* @brief set pulse width. | |
*/ | |
void wy_PWM_handle (wy_PWM_WiDTH_TypeDef _w) | |
{ | |
TIM_SetCompare3(TIM4, _w); | |
} | |
/** | |
* @brief handle command by calling relevant functions. | |
*/ | |
void wy_CommandHandle(Command _c) | |
{ | |
switch (_c) | |
{ | |
case '0' : wy_PWM_handle(wy_PWM_0_DeGREE ); | |
break; | |
case '1' : wy_PWM_handle(wy_PWM_10_DeGREE ); | |
break; | |
case '2' : wy_PWM_handle(wy_PWM_20_DeGREE ); | |
break; | |
case '3' : wy_PWM_handle(wy_PWM_30_DeGREE ); | |
break; | |
case '4' : wy_PWM_handle(wy_PWM_40_DeGREE ); | |
break; | |
case '5' : wy_PWM_handle(wy_PWM_50_DeGREE ); | |
break; | |
case '6' : wy_PWM_handle(wy_PWM_60_DeGREE ); | |
break; | |
case '7' : wy_PWM_handle(wy_PWM_70_DeGREE ); | |
break; | |
case '8' : wy_PWM_handle(wy_PWM_80_DeGREE ); | |
break; | |
case '9' : wy_PWM_handle(wy_PWM_90_DeGREE ); | |
break; | |
case 'n' : wy_PWM_handle(wy_PWM_45_DeGREE ); | |
break; | |
case 'N' : wy_PWM_handle(wy_PWM_45_DeGREE ); | |
break; | |
case 'w' : wy_WindScreen(); | |
break; | |
case 'W' : wy_WindScreen(); | |
break; | |
} | |
} | |
/** | |
* @brief move the arm back and forth continuously. | |
*/ | |
void wy_WindScreen (void) | |
{ | |
int cmd=1000; | |
wy_PWM_handle(wy_PWM_0_DeGREE); | |
delay_millisec(400); | |
while(! is_uart_data_ready()) | |
{ | |
while( (cmd<2000) & (! is_uart_data_ready())) | |
{ | |
wy_PWM_handle(cmd); | |
delay_millisec(10); | |
cmd += 10 ; | |
} | |
while( (cmd>1000) & (! is_uart_data_ready())) | |
{ | |
wy_PWM_handle(cmd); | |
delay_millisec(10); | |
cmd -= 10 ; | |
} | |
} | |
} | |
/** | |
* @brief millisecond delay. | |
*/ | |
void delay_millisec(register unsigned short n) | |
{ | |
if (n > 5) n -= 5; | |
else n = 1; | |
TIM6->PSC = 23999; | |
TIM6->ARR = n; | |
TIM6->CNT = 0; | |
TIM6->EGR = TIM_EGR_UG; | |
TIM6->CR1 |= (TIM_CR1_OPM | TIM_CR1_CEN); | |
while (TIM6->CR1 & TIM_CR1_CEN); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment