钻石会员
  
主题
帖子
积分11972
阅读权限50
注册时间2012-11-19
最后登录1970-1-1
在线时间 小时
|
本帖最后由 holts 于 2012-11-28 23:47 编辑
程序可以用STM的库, 很方便的, 支持ISP下载. 可以到官网下载开发工具 ST Visual Develop, 当然也可以用IAR, Keil 第三方的软件, 下面的程序是在 LCD1602第一行显示动态的状态条, 第二行上显示 时间, 准备调试加入声音, 加DDS输出, 你看下程序应该知道对你来说难度不大.
/**
******************************************************************************
* @file Project/main.c
* @author MCD Application Team
* @version V1.0.0
* @date 16_January-2012
* @brief Main program body
******************************************************************************
* @attention
*
* THE PRESENT FIRMWARE WHICH IS FOR GUIDANCE ONLY AIMS AT PROVIDING CUSTOMERS
* WITH CODING INFORMATION REGARDING THEIR PRODUCTS IN ORDER FOR THEM TO SAVE
* TIME. AS A RESULT, STMICROELECTRONICS SHALL NOT BE HELD LIABLE FOR ANY
* DIRECT, INDIRECT OR CONSEQUENTIAL DAMAGES WITH RESPECT TO ANY CLAIMS ARISING
* FROM THE CONTENT OF SUCH FIRMWARE AND/OR THE USE MADE BY CUSTOMERS OF THE
* CODING INFORMATION CONTAINED HEREIN IN CONNECTION WITH THEIR PRODUCTS.
*
* FOR MORE INFORMATION PLEASE READ CAREFULLY THE LICENSE AGREEMENT FILE
* LOCATED IN THE ROOT DIRECTORY OF THIS FIRMWARE PACKAGE.
*
* <h2><center>© COPYRIGHT 2011 STMicroelectronics</center></h2>
******************************************************************************
*/
/* Includes ------------------------------------------------------------------*/
#include "stm8s.h"
#include "main.h"
#include "HD44780.h"
#include "delay.h"
#include "pt.h"
#include "math.h"
/* Private defines -----------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/
/* Global variables*/
volatile bool event = TRUE;
volatile bool timeON = FALSE;
volatile bool ButtonPressed = FALSE;
volatile u16 ten_ms = 0;
volatile u16 sec = 0;
volatile u16 min = 0;
volatile u8 KeyDelay;
volatile u16 DispDelay;
/* Global variable used to store the ADC result. */
volatile u16 ad_value;
u16 pwm_duty[100];
u8 Trg;
u8 Cont;
static struct pt pt1,pt2;
/* Define 6 custom characters to display bar graph*/
char STCustom[48] =
{
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // Blank
0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, 0x10, // 1column |
0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, 0x18, // 2columns ||
0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, 0x1c, // 3columns |||
0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, 0x1e, // 4columns ||||
0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, // 5columns |||||
};
//xdata struct Ida{
// char zo[3];//三个频率下的零点改正值
// char j1; //相位补偿(3倍档)
// char j2; //相位补偿(10倍档)
// char J[4]; //相位补偿(V/I变换器)
// char R[4]; //下臂电阻修正(20,1k,10k,100k)
// char g1; //增益修正(3倍档)
// char g2; //增益修正(10倍档)
// char phx; //1kHz以下相位改正
// char R4b; //100k档7.8kHz频率下的幅度补偿
// char G2b; //9倍档7.8kHz频率下的幅度补偿
// char feq; //频率修正
// char ak; //AD斜率修正
//} cs;
u16 i, count;
u8 char_pos, roll, s;
/* Custom characters can be 8 max. user defined characters from 0 to 7*/
/* disp[] string is here to generate the display of custom characters on LCD*/
/* of the bar graph using 8 characters pattern*/
/* Example: printing "\0\0\0\0\0\0\0\0\n" will display 8 times character 0*/
/* which is the blank character*/
/* Example: printing "\5\5\5\5\5\5\5\5\n" will display 8 times character 5*/
/* which is the 5 columns character*/
char disp[] = "\0\0\0\0\0\0\0\0\n";
char message[5][7] = {"STM8S", "Value", "Line", "8-Bit", "Micro"};
void main(void)
{
/* Init CLK */
CLK_Configuration();
/* Init GPIOs*/
/* This function sets GPIOs pins according to LCD pins assignment in main.h*/
GPIO_Configuration();
BEEP_DeInit();
TIM1_Config();
/* TIM4 configuration */
TIM4_Config();
/* Enable interrupts */
enableInterrupts();
/* Set power supply on LCD via LCD Power Pin */
LCD_PWRON();
/* Min. delay to wait before initialization after LCD power ON */
/* Value is ms units*/
Delay(100);
/* Initialization of LCD */
LCD_INIT();
/* LCD Clear Display */
LCD_CLEAR_DISPLAY();
/* Set @CGRAM address start */
LCD_CMD(CGRAM_address_start);
/* Loading 6 characters @CGRAM address from STCustom tab */
LCD_LOAD_CGRAM(STCustom, 6);
/* Welcome application message while delay 6000ms */
/* Set cursor to the chosen position*/
LCD_LOCATE(1, 1);
/* Print string on LCD (must be ended with \n)*/
LCD_printstring(" LCR 2.0 \n");
LCD_LOCATE(2, 2);
LCD_printstring("XJW Putian,2011\n");
Delay(6000);
LCD_CLEAR_DISPLAY();
/* Init local variables*/
roll = 0;
count = 0;
s = 0;
/* Init global variables*/
ten_ms = 0;
sec = 0;
min = 0;
/* Enable time counter display*/
timeON = TRUE;
for(i=0; i<100; i++)
{
#if FRQ_100HZ
//pwm_duty=(unsigned int)(55+(float)55*sin(2*3.1415926*(float)i*0.2/(float)20));
#else
//pwm_duty=(unsigned int)(110+(float)110*sin(2*3.1415926*(float)i*0.2/(float)20));
#endif
}
/* Initialize the protothread state variables with PT_INIT(). */
PT_INIT(&pt1);
PT_INIT(&pt2);
/* Purpose of this brief LCD demo is to simultaneously display 4 different items*/
/* on the 2-line LCD combining some of the LCD library resources*/
/* A 8-character pattern bar graph which is progressively incremented*/
/* The square value of a count variable between 0 up to 128*/
/* A time counter displaying minutes, seconds, tenth and hundredth of seconds*/
/* A rolling ASCII message changing every second*/
while (1)
{
/* 键盘处理 */
Key_thread(&pt1);
/* Check button status */
if (ButtonPressed == TRUE) /* Button is pressed */
{
ButtonPressed = FALSE;
/* Change BEEP frequency */
switch (s)
{
case 0:
BEEP_Cmd(DISABLE);
Delay(100);
BEEP_Init(BEEP_FREQUENCY_1KHZ);
BEEP_Cmd(ENABLE);
//LCD_SetCursorPos(LCD_LINE1, 0);
//LCD_Print(" BEEPER 1kHz ");
s = 1;
break;
case 1:
BEEP_Cmd(DISABLE);
Delay(100);
BEEP_Init(BEEP_FREQUENCY_2KHZ);
BEEP_Cmd(ENABLE);
//LCD_SetCursorPos(LCD_LINE1, 0);
//LCD_Print(" BEEPER 2kHz ");
s = 2;
break;
case 2:
BEEP_Cmd(DISABLE);
Delay(100);
BEEP_Init(BEEP_FREQUENCY_4KHZ);
BEEP_Cmd(ENABLE);
//LCD_SetCursorPos(LCD_LINE1, 0);
//LCD_Print(" BEEPER 4kHz ");
s = 3;
break;
case 3:
BEEP_Cmd(DISABLE);
//LCD_SetCursorPos(LCD_LINE1, 0);
//LCD_Print(" BEEPER OFF ");
s = 0;
break;
default:
break;
}
}
/* 显示处理 */
Display_thread(&pt2);
}
}
/**
******************************************************************************
* @brief Configures clocks
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void CLK_Configuration(void)
{
/* Fmaster = 16MHz */
CLK_HSIPrescalerConfig(CLK_PRESCALER_HSIDIV1);
}
/**
******************************************************************************
* @brief Configures GPIOs
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void GPIO_Configuration(void)
{
/* GPIO reset */
GPIO_DeInit(LCDPort);
/* Configure LCDPort D0 output push-pull low LCD Bus*/
GPIO_Init(LCDPort, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
/* Configure LCDPort D1 output push-pull low LCD Bus*/
GPIO_Init(LCDPort, GPIO_PIN_1, GPIO_MODE_OUT_PP_LOW_FAST);
/* Configure LCDPort D2 output push-pull low LCD Bus*/
GPIO_Init(LCDPort, GPIO_PIN_2, GPIO_MODE_OUT_PP_LOW_FAST);
/* Configure LCDPort D3 output push-pull low LCD Bus*/
GPIO_Init(LCDPort, GPIO_PIN_3, GPIO_MODE_OUT_PP_LOW_FAST);
/* GPIO reset */
GPIO_DeInit(LCDControlPort);
/* Configure LCDPort E output push-pull low LCD Enable Pin*/
GPIO_Init(LCDControlPort, LCD_Enable, GPIO_MODE_OUT_PP_LOW_FAST);
/* Configure LCDPort RS output push-pull low LCD RS Pin*/
GPIO_Init(LCDControlPort, LCD_RS, GPIO_MODE_OUT_PP_LOW_FAST);
/* GPIO reset */
GPIO_DeInit(LCDPwrPort);
/* Configure LCDPwrOnPort VDD output push-pull low LCD Power Supply*/
GPIO_Init(LCDPwrPort, LCDPwrPin, GPIO_MODE_OUT_PP_LOW_FAST);
/* GPIOD reset */
//GPIO_DeInit(BUTTON_PORT);
/* Configure PC4 (push button) as input floating */
GPIO_Init(BUTTON_PORT, BUTTON_PIN, GPIO_MODE_IN_PU_IT);
/* Configure PD0 (LED1) as output push-pull low (led switched on) */
//GPIO_Init(GPIOD, GPIO_PIN_0, GPIO_MODE_OUT_PP_LOW_FAST);
}
/**
******************************************************************
* @brief TIM1 init
* @par Parameters: None
* @retval void None
* @par Required preconditions: None
******************************************************************
*/
void TIM1_Config(void)
{
TIM1_DeInit();
/* Time Base configuration */
/*
TIM1_Prescaler = 128 分频16/128 = 125 KHz
TIM1_Period = 124 频率125K /(124+1) = 100Hz
TIM1_CounterMode = TIM1_COUNTERMODE_UP
TIM1_RepetitionCounter = 0
*/
TIM1_TimeBaseInit(128, TIM1_COUNTERMODE_UP, FRQ_100HZ, 0);
/* Channel 2 Configuration in PWM mode */
/*
TIM1_OCMode = TIM1_OCMODE_PWM2
TIM1_OutputState = TIM1_OUTPUTSTATE_ENABLE
TIM1_OutputNState = TIM1_OUTPUTNSTATE_ENABLE
TIM1_Pulse = DutyCycle
TIM1_OCPolarity = TIM1_OCPOLARITY_LOW
TIM1_OCNPolarity = TIM1_OCNPOLARITY_HIGH
TIM1_OCIdleState = TIM1_OCIDLESTATE_SET
TIM1_OCNIdleState = TIM1_OCIDLESTATE_RESET
*/
TIM1_OC1Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, FRQ_100HZ/2,
TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_SET,
TIM1_OCNIDLESTATE_RESET);
TIM1_OC2Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, FRQ_100HZ/2,
TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_SET,
TIM1_OCNIDLESTATE_RESET);
TIM1_OC3Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, TIM1_OUTPUTNSTATE_ENABLE, FRQ_100HZ/2,
TIM1_OCPOLARITY_LOW, TIM1_OCNPOLARITY_HIGH, TIM1_OCIDLESTATE_SET,
TIM1_OCNIDLESTATE_RESET);
TIM1_OC4Init(TIM1_OCMODE_PWM2, TIM1_OUTPUTSTATE_ENABLE, FRQ_100HZ/2, TIM1_OCPOLARITY_LOW,
TIM1_OCIDLESTATE_SET);
/* TIM1 counter enable */
TIM1_Cmd(ENABLE);
/* TIM1 Main Output Enable */
TIM1_CtrlPWMOutputs(ENABLE);
}
/**
*****************************************************************
* @brief Configure TIM4 to generate an update interrupt each 1ms
* @param None
* @retval None
*****************************************************************
*/
void TIM4_Config(void)
{
/* TIM4 configuration:
- TIM4CLK is set to 16 MHz, the TIM4 Prescaler is equal to 128 so the TIM1 counter
clock used is 16 MHz / 128 = 125 000 Hz
- With 125 000 Hz we can generate time base:
max time base is 2.048 ms if TIM4_PERIOD = 255 --> (255 + 1) / 125000 = 2.048 ms
min time base is 0.016 ms if TIM4_PERIOD = 1 --> ( 1 + 1) / 125000 = 0.016 ms
- In this example we need to generate a time base equal to 1 ms
so TIM4_PERIOD = (0.001 * 125000 - 1) = 124 */
/* Time base configuration */
TIM4_TimeBaseInit(TIM4_PRESCALER_128, TIM4_PERIOD_MS);
/* Clear TIM4 update flag */
TIM4_ClearFlag(TIM4_FLAG_UPDATE);
/* Enable update interrupt */
TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);
/* Enable TIM4 */
TIM4_Cmd(ENABLE);
}
/**
******************************************************************
* @brief Key Read
* @par Parameters: None
* @retval void None
* @par Required preconditions: None
******************************************************************
*/
void KeyRead( void )
{
//unsigned char ReadData = GPIO_ReadInputData(KEY_GPIO_PORT)^0xFF;
//ReadData = ReadData & 0x0E;
u8 ReadData = (GPIO_ReadInputData(BUTTON_PORT)^0x80) & 0x80 ;
Trg = ReadData & (ReadData ^ Cont);
Cont = ReadData;
}
/**
******************************************************************
* @brief Delay before completing the action
* @param[in] function action() to be performed once the delay past
* @param[in] None
* @retval void None
* @par Required preconditions: None
******************************************************************
*/
static int Key_thread(struct pt *pt)
{
PT_BEGIN(pt);
/* Start with first character of bar graph*/
char_pos = 0;
/* Display 8-character pattern bar graph, (count)^2 value, time counter, rolling message*/
while (char_pos < 8)
{
/* If event true (1 sec elapsed) then display rolling messages*/
if (event == TRUE)
{
event = FALSE;
LCD_LOCATE(2, 11);
/* Message is displayed at the bottom right*/
/* Uses special mask*/
LCD_printf("%5s", message[roll]);
/* Message changes every time (5 times) then return to first word*/
/* Table index "roll" is set accordingly*/
roll = (roll + 1) % 5;
}
/* Display each 6 (0 to 5) custom characters at same LCD position*/
for (i = 0;i < 6;i++)
{
/* Display bar graph at the top left*/
LCD_LOCATE(1, 1);
LCD_printstring(disp);
/* Change custom character to be displayed 0->1->2->3->4->5*/
disp[char_pos] = (disp[char_pos] + 1);
/* Display count value*/
LCD_LOCATE(1, 11);
/* Display (count^2) value at the top right*/
/* Uses special mask*/
LCD_printf("%5d", count*count);
count++;
/* Reset count variable if upper than 128*/
if (count > 128)
count = 0;
/* Display time counter Min:Sec:Ten ms at the bottom left*/
LCD_LOCATE(2, 1);
/* Uses special mask*/
LCD_printf("%02d:%02d:%02d", min, sec, ten_ms);
}
/* if custom character 5 reached (all columns filled) maintain it display */
disp[char_pos] = 5;
/* and move to next position of bar graph*/
char_pos++;
}
/* Reset bar graph display to blank*/
for (i = 0;i < 8;i++)
disp = 0;
/* Blink display and wait for a while*/
LCD_DISP_OFF();
//Delay(300);
DispDelay = 300;
PT_WAIT_UNTIL(pt,DispDelay==0);
LCD_DISP_ON();
//Delay(1000);
DispDelay = 1000;
PT_WAIT_UNTIL(pt,DispDelay==0);
PT_END(pt);
}
/**
******************************************************************
* @brief Delay before completing the action
* @param[in] function action() to be performed once the delay past
* @param[in] None
* @retval void None
* @par Required preconditions: None
******************************************************************
*/
static int Display_thread(struct pt *pt)
{
PT_BEGIN(pt);
KeyRead();
if (Trg)
{
//timer_set(&timer, T_AWAKE);
//PT_WAIT_UNTIL(pt, timer_expired(&timer));
//timer_set(&timer, T_SLEEP);
KeyDelay = 20 ;
PT_WAIT_UNTIL(pt,KeyDelay==0);
KeyRead();
if(Cont)
{
if (Cont & BUTTON_PIN)
{ ButtonPressed = TRUE; }
if (Cont & KEY_REDUCE)
{ ButtonPressed = TRUE; }
if (Cont & KEY_POWER)
{ ButtonPressed = TRUE; }
}
}
PT_END(pt);
}
/**
******************************************************************************
* @brief Toggle PD0 (Led LD1)
* @par Parameters:
* None
* @retval void None
* @par Required preconditions:
* None
******************************************************************************
*/
void Toggle(void)
{
// GPIO_WriteReverse(GPIOD, GPIO_PIN_0);
}
#ifdef USE_FULL_ASSERT
/**
* @brief Reports the name of the source file and the source line number
* where the assert_param error has occurred.
* @param file: pointer to the source file name
* @param line: assert_param error line source number
* @retval : None
*/
void assert_failed(u8* file, u32 line)
{
/* User can add his own implementation to report the file name and line number,
ex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */
/* Infinite loop */
while (1)
{}
}
#endif |
|