您的位置 首页 应用

根据STM8的ADC0832收集及蓝牙通讯体系

最近在淘宝逛的时候发现了一款单片机,STM8。相比之前一直使用的也是8位的AVR相比,感觉STM8更为强大,芯片特点如下:内核:具有3级流水线的哈佛结构、扩展指令集程序存储器:8K字节Fl

  最近在淘宝逛的时分发现了一款单片机,STM8。比较之前一向运用的也是8位的AVR比较,感觉STM8更为强壮,芯片特色如下:

  内核:具有3级流水线的哈佛结构、扩展指令集

  程序存储器:8K字节Flash;RAM:1K字节

  数据存储器:640 字节真实的数据EEPROM;可达30万次擦写

  更重要的一点便是STM8系列若运用库编程的话,能够便利的不同芯片的程序移植。乃至能够便利的移植到STM32上面,大大减轻了更新硬件的重写程序的工作量。

  ADC0832 为8位分辩率A/D转化芯片,其最高分辩可达256级,能够习惯一般的模仿量转化要求。其内部电源输入与参阅电压的复用,使得芯片的模仿电压输入在0~5V之间。芯片转化时刻仅为32μS,据有双数据输出可作为数据校验,以削减数据误差,转化速度快且安稳功用强。独立的芯片使能输入,使多器材挂接和处理器操控变的愈加便利。经过DI 数据输入端,能够容易的完成通道功用的挑选。(简述和图片均来之百度百科)

    

 

  本文合适STM8操控ADC0832,程序是运用库编程,编译东西IAR。其实STM8也自带ADC转化模块了……

  本程序还包含蓝牙串口通讯,便利将得到数据从串口输出,我是编写了安卓上位机的app,便利在安卓上面显现图画。

  程序仍是用了定时器TIM4,保证每次采样的距离大致持平,对之后的数据处理供给了根底。

  先介绍中心mian.c文件,主要功用是初始化串口UART1,定时器TIMER4,还有一个发送16进制的函数。其间发送完数据再发送一个字符’U’作为一个数据的完毕(你也能够自己界说)。这儿说说为什么要选用16进制,而不是10进制,STM8速度有限,为了削减单指令操作,程序用了移位操作,这样可得到16进制每位数值,在发送到安卓上位机,上位机运算速度快,再转化成10进制,这样能够资源合理分配。

  main.c程序:

  #include "stm8s.h"

  #include "stm8s_it.h"

  uint8_t HexTable[]={'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};

  uint8_t i=0;

  //串口UART1初始化

  void Init_UART(void)

  {

  //默许初始化

  UART1_DeInit();

  //设置波特率9600 8位数据 1位中止位 无校验 外部时钟不可用 形式接纳发送

  UART1_Init((u32)9600, UART1_WORDLENGTH_8D, UART1_STOPBITS_1, UART1_PARITY_NO, UART1_SYNCMODE_CLOCK_DISABLE, UART1_MODE_TXRX_ENABLE);

  //设置接纳寄存器溢出中止

  UART1_ITConfig(UART1_IT_RXNE_OR, ENABLE);

  }

  //定时器TIM4初始化

  void Init_Timer4(void)

  {

  //1ms中止一次

  TIM4_TimeBaseInit(TIM4_PRESCALER_128, 124);

  /* Clear TIM4 update flag */

  TIM4_ClearFlag(TIM4_FLAG_UPDATE);

  /* Enable update interrupt */

  TIM4_ITConfig(TIM4_IT_UPDATE, ENABLE);

  TIM4_Cmd(ENABLE);

  }

  //发送字节

  void Send(uint8_t dat)

  {

  //查看并等候发送寄存器是否为空

  while(( UART1_GetFlagStatus(UART1_FLAG_TXE)==RESET));

  //发送字节

  UART1_SendData8(dat);

  }

  //发送16位16进制

  void UART1_mysend16hex(u16 dat)

  {

  Send(HexTable[(dat>>12)&0x0f]);

  Send(HexTable[(dat>>8)&0x0f]);

  Send(HexTable[(dat>>4)&0x0f]);

  Send(HexTable[(dat)&0x0f]);

  }

  //发送8位16进制

  void UART1_mysend8hex(uint8_t dat)

  {

  Send(HexTable[(dat>>4)&0x0f]);

  Send(HexTable[(dat)&0x0f]);

  Send('U');

  }

  void main()

  {

  //初始化

  Init_UART();

  Init_Timer4();

  //中止敞开

  enableInterrupts();

  while(1)

  {

  }

  }

  //这个有必要加上 否则会报错 估量是库的要求

  #ifdef USE_FULL_ASSERT

  void assert_failed(u8* file, u32 line)

  {

  while (1)

  {

  }

  }

  #endif

  接下来说说中止函数表stm8s_it.c

  其间只需选用两个中止函数就能够了:

  INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18) 接纳寄存器溢出中止

  里边增加安卓上位机发送过来的数据的处理程序,我这儿写的是ADC0832通道挑选的判别。

  INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23) 定时器4计数器溢出中止

  里边增加初始化ADC0832和ADC0832数据读取并UART1发送到安卓上位机。

  stm8s_it.c程序:

  #include "stm8s_it.h"

  #include "ADC0832.h"

  extern uint8_t i;

  uint8_t channel=1 ;

  //接纳寄存器溢出中止

  INTERRUPT_HANDLER(UART1_RX_IRQHandler, 18)

  {

  /* In order to detect unexpected events during development,

  it is recommended to set a breakpoint on the following instruction.

  */

  //下面是我做的安卓上位机发送过来的数据判别,这儿能够改成自己想要的程序

  uint8_t tempData;

  tempData = UART1_ReceiveData8();

  if(tempData=='A')

  {

  channel = 0;

  }

  if(tempData=='Z')

  {

  channel = 1;

  }

  //铲除UART1中止标识符

  UART1_ClearITPendingBit(UART1_IT_RXNE);

  }

  //定时器4计数器溢出中止

  INTERRUPT_HANDLER(TIM4_UPD_OVF_IRQHandler, 23)

  {

  /* In order to detect unexpected events during development,

  it is recommended to set a breakpoint on the following instruction.

  */

  //1*10m履行一次

  i++;

  if(i==10)

  {

  //进行ADC数模转化

  //初始化ADC芯片,写入通道

  AD_init(channel);

  u8 u8_adc1_value;

  //进行数据读出

  u8_adc1_value = AD_read();

  //发送8位数据

  UART1_mysend8hex(u8_adc1_value);

  //铲除UART1中止标识符

  UART1_ClearITPendingBit(UART1_IT_RXNE);

  i=0;

  }

  TIM4_ClearITPendingBit(TIM4_IT_UPDATE);

  }

  这儿说说ADC0832的操作函数:ADC0832.c

  程序包含初始化STM8的GPIO,初始化ADC0832和读取ADC0832数据

  主要是DODI端口复用的问题,因为STM8端口作为输入输出,需求从头初始化GPIO,所以比一般51单片机的程序要杂乱一点。最终读取数据先是从高位读出,再低位读出,进行校验,相同数值再输出。

  附上时序图

    

 

  ADC0832.c程序:

  /**********************************************

  程序称号:ADC0832子程序

  作 者:devinzhang91

  时 间:2014.10.04

  **********************************************/

  #ifndef ADC0832_H

  #define ADC0832_H

  #include "stm8s.h"

  //端口设置

  #define CLK_GPIO_PORT (GPIOC)

  #define CLK_GPIO_PINS (GPIO_PIN_3)

  #define DI_GPIO_PORT (GPIOC)

  #define DI_GPIO_PINS (GPIO_PIN_4)

  #define DO_GPIO_PORT (GPIOC)

  #define DO_GPIO_PINS (GPIO_PIN_4)

  #define CS_GPIO_PORT (GPIOC)

  #define CS_GPIO_PINS (GPIO_PIN_1)

  /********************************************************

  函数称号:void ioInit(void)

  函数效果:初始化GPIO

  参数阐明:null

  ********************************************************/

  void ioInit(void)

  {

  {

  //全为输出形式

  GPIO_Init(CLK_GPIO_PORT, CLK_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_FAST);

  GPIO_Init(DI_GPIO_PORT, DI_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_FAST);

  GPIO_Init(DO_GPIO_PORT, DO_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_FAST);

  GPIO_Init(CS_GPIO_PORT, CS_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_FAST);

  }

  /********************************************************

  函数称号:void ioChange()

  函数效果:初始化GPIO

  参数阐明:i=0,表明输出,i=1,表明输入

  ********************************************************/

  void ioChange(uchar i)

  {

  if( i == 0)

  GPIO_Init(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS, GPIO_MODE_OUT_PP_LOW_FAST);

  if( i == 1)

  GPIO_Init(DI_GPIO_PORT, (GPIO_Pin_TypeDef)DI_GPIO_PINS, GPIO_MODE_IN_PU_NO_IT);

  }

  /********************************************************

  函数称号:void AD_init(uchar i)

  函数效果:初始化ADC0832

  参数阐明:i=0,表明通道0,i=1,表明通道1

  ********************************************************/

  void AD_init(uchar i)

  {

  ioInit(); //初始化io

  ioChange(0); //作为输出

  GPIO_WriteLow(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS); //构成下降沿

  asm("nop");

  asm("nop");

  GPIO_WriteHigh(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS); /*在第1 个时钟脉冲的下沉之前DI端有必要是高电平,表明启始信号*/

  asm("nop");

  asm("nop");

  GPIO_WriteLow(CS_GPIO_PORT, (GPIO_Pin_TypeDef)CS_GPIO_PINS); //使能ADC0832

  asm("nop");

  asm("nop");

  GPIO_WriteHigh(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteLow(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS); //构成下降沿1

  asm("nop");

  asm("nop"); /*在第2、3个脉冲下沉之前DI端应输入2位数据用于挑选通道功用*/

  if( i==0 )

  GPIO_WriteLow(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS);

  if( i==1 )

  GPIO_WriteHigh(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteHigh(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteLow(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS); //构成下降沿2

  asm("nop");

  asm("nop");

  if( i==0 )

  GPIO_WriteLow(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS);

  if( i==1 )

  GPIO_WriteHigh(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS);

  GPIO_WriteHigh(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteLow(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS); //构成下降沿3

  asm("nop");

  asm("nop");

  }

  /********************************************************

  函数称号:uchar AD_read()

  函数效果:读取ADC0832转化的数据

  参数阐明:无

  函数回来:回来8位的数据

  ********************************************************/

  u8 AD_read()

  {

  u8 temp1 = 0;

  u8 temp2 = 0;

  uchar i = 0;

  GPIO_WriteHigh(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS);

  asm("nop");

  asm("nop");

  ioChange(1); //作为输入

  for(i = 0; i < 8; i++)

  {

  GPIO_WriteHigh(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteLow(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS); //构成下降沿

  asm("nop");

  asm("nop");

  temp1 = temp1 << 1;

  if(GPIO_ReadInputPin(DI_GPIO_PORT, (GPIO_Pin_TypeDef)DI_GPIO_PINS) !=0)

  temp1 |= 0x01;

  else temp1 |= 0x00;

  }

  for(i = 0; i < 8; i++)

  {

  temp2 = temp2>>1;

  if(GPIO_ReadInputPin(DI_GPIO_PORT, (GPIO_Pin_TypeDef)DI_GPIO_PINS) !=0)

  temp2 = temp2|0x80;

  GPIO_WriteHigh(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteLow(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS); //构成下降沿

  asm("nop");

  asm("nop");

  }

  GPIO_WriteHigh(CLK_GPIO_PORT, (GPIO_Pin_TypeDef)CLK_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteHigh(DO_GPIO_PORT, (GPIO_Pin_TypeDef)DO_GPIO_PINS);

  asm("nop");

  asm("nop");

  GPIO_WriteHigh(CS_GPIO_PORT, (GPIO_Pin_TypeDef)CS_GPIO_PINS); //使能ADC0832

  asm("nop");

  asm("nop");

  if(temp1 == temp2)

  return temp1;

  else

  return 0;

  }

  #endif

  再说说安卓上位机,一个简略蓝牙接纳的apk,用于实时画图,能够显现和画出一段时刻内的STM8采样的数值,从后台接纳数据,发送音讯至进程更新UI。

  为了便利我们学习,工程现已打包上传,http://download.csdn.net/detail/devintt/8029389

声明:本文内容来自网络转载或用户投稿,文章版权归原作者和原出处所有。文中观点,不代表本站立场。若有侵权请联系本站删除(kf@86ic.com)https://www.86ic.net/yingyong/184003.html

为您推荐

联系我们

联系我们

在线咨询: QQ交谈

邮箱: kf@86ic.com

关注微信
微信扫一扫关注我们

微信扫一扫关注我们

返回顶部