一乐电子

一乐电子百科

 找回密码
 请使用微信账号登录和注册会员

QQ登录

只需一步,快速开始

快捷登录

手机号码,快捷登录

搜索
查看: 27443|回复: 96
收起左侧

stm32怎么学

  [复制链接]
发表于 2012-11-28 22:10 | 显示全部楼层 |阅读模式
本帖最后由 xjw01 于 2012-11-29 06:42 编辑

坛友说STM32制作LCR比较好。
我想试一下。
如何选型,如何编写一个LED流水灯与AD转换程序;这两个会了,LCR就能写出来。(我有多年的电脑程序经历,算法功底也不错)。
stm32的AD是否独立电源?
stm32耗电吗?
stm32的C编程工具好用吗?
可我不懂stm32。要找一些什么资料,买些什么工具。
发表于 2012-11-28 22:32 | 显示全部楼层
有51基础, 换单片机, 难度不高的, 用C编程, 移植也比较容易, 当然了解指令集会更好.
应该是用STM8制作LCR吧,都是8位单片机.
STM用什么开发软件, 买什么工具, 我未接触过, 有熟悉的人介绍下,  或组织团购工具等.
发表于 2012-11-28 22:34 | 显示全部楼层
期待许老师的大作。用SMT32的话,测试频率可以提高不少。
发表于 2012-11-28 23:05 | 显示全部楼层
lcr就好比换了一个脑袋啊,处理问题的能力提高很多啊,期待。。。。
发表于 2012-11-28 23:08 | 显示全部楼层
T1dl6oXixXXXb4CUEU_015956.jpg_310x310.jpg

许老师, 建议用STM32F0 ,   直接进入32位时代,   成本也就6-8元左右 ,    做成很强的台表.


当然 也可以用STM8 ,    会C应该很快上手的,  不难,    我手上有块STM8S的板子, 如果你决定用 STM8S, 我可以把板子寄给你做程序的移植.

stm8s.JPG
发表于 2012-11-28 23:13 | 显示全部楼层
1.STM32,ref有没有外接引脚要看封装,印象中100脚以上的是有外接ref的.
2.STM32说是比51省电.
3.STM32可以用keilMDK编程调试,ISP下载.
如果你有STlink.或ulink就更理想了.

不过你可以考虑下新唐的M0,他们的编程调试工具很容易拿到.
发表于 2012-11-28 23:14 | 显示全部楼层
另外一般厂家给M0,M3系列单片机配的ADC是12位的,
比51分辨率高.
发表于 2012-11-28 23:17 | 显示全部楼层
许老师大改版了,要顶一下,就是标题要写清楚点,有的人估计会看得云里雾里的
发表于 2012-11-28 23:22 | 显示全部楼层
本帖最后由 holts 于 2012-11-28 23:47 编辑

程序可以用STM的库, 很方便的, 支持ISP下载. 可以到官网下载开发工具 ST Visual Develop, 当然也可以用IAR, Keil 第三方的软件, 下面的程序是在 LCD1602第一行显示动态的状态条, 第二行上显示 时间,  准备调试加入声音, 加DDS输出,  你看下程序应该知道对你来说难度不大.

P1040114a.jpg

/**
  ******************************************************************************
  * @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>&copy; 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
发表于 2012-11-28 23:25 | 显示全部楼层
回复 6# yanjian

不要新塘的, 新塘的M0是 10位ADC

本版积分规则

QQ|一淘宝店|手机版|商店|电子DIY套件|一乐电子 ( 粤ICP备09076165号 ) 公安备案粤公网安备 44522102000183号

GMT+8, 2024-3-29 19:02 , Processed in 0.062602 second(s), 37 queries , Gzip On.

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表