You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

82 lines
2.3 KiB

  1. #include "port.h"
  2. #include "systick.h"
  3. static ADC_InitStruType x;
  4. static GPIO_InitSettingType y;
  5. static bool adccapture_error = false;
  6. static uint16_t prv_adc_get_value() {
  7. ErrorStatus status = ADC_SoftStart();
  8. adccapture_error = false;
  9. if (status != SUCCESS) {
  10. adccapture_error = true;
  11. return 0;
  12. }
  13. uint32_t inticket = get_sys_ticket();
  14. while (ADC_GetConvStatus() != RESET) {
  15. if (port_haspassedms(inticket) > 10) {
  16. adccapture_error = true;
  17. return 0;
  18. }
  19. }
  20. uint16_t adcv = ADC_GetConvValue();
  21. ADC_SoftStop();
  22. return adcv ;
  23. }
  24. static void prv_adc_pb9_init() {
  25. y.Signal = GPIO_Pin_Signal_Analog; //模拟
  26. y.Dir = GPIO_Direction_Input; //输入
  27. y.Func = GPIO_Reuse_Func0;
  28. // x.CHS设置adc采集的通道每个引脚对应一个通道
  29. GPIO_Init(GPIO_Pin_B9, &y);
  30. //经过分频以后Tadclk=1/(PCLK/32)
  31. x.CLKS = ADC_CLKS_PCLK;
  32. x.CLKDIV = ADC_CLKDIV_1_32; /* ADC时钟源预分频 */
  33. //采集到的模拟量*3.3/4096=现在的电压
  34. x.VREF_SEL = ADC_VREF_SEL_0; /* 内部参考电压2.048v,仅设置内部参考电压为多少 */
  35. x.VREFP = ADC_VREFP_VDD; /* 选择芯片的工作电压VDD,这个是设置adc具体是要哪个电压来做参考adc的参考电压为多少 */
  36. x.VREFN = ADC_VREFN_VSS; /* 负向参考电压选择 */
  37. x.CHS = ADC_CHS_AIN4;
  38. // x.CHS = ADC_CHS_AIN8;
  39. x.SMPS = ADC_SMPS_SOFT; /* AD采样模式为软件控制 */
  40. //采样时间st*2+1(个Tadclk)=1.743us
  41. x.ST = 0; /* AD硬件采样时间选择 */
  42. x.BITSEL = ADC_BITSEL_8; /* AD分辨率12位 */
  43. ADC_Init(&x);
  44. prv_adc_get_value();
  45. }
  46. extern uint32_t getCNT();
  47. extern uint32_t getTOP();
  48. uint16_t capture(int timeoff) {
  49. static bool inited = false;
  50. if (inited == false) {
  51. prv_adc_pb9_init();
  52. inited = true;
  53. }
  54. uint16_t expectCNTBegin = getTOP() / 100.0 * timeoff;
  55. uint16_t expectCNTEnd = getTOP() / 100.0 * (timeoff + 1);
  56. // printf("%d %d , %d\n", timeoff, expectCNTBegin, expectCNTEnd);
  57. int icount = 0;
  58. while (true) {
  59. volatile uint16_t countnow = T16Nx_GetCNT1(T16N0);
  60. // printf("%d\n",countnow);
  61. for (size_t i = 0; i < icount % 10; i++) {
  62. }
  63. icount++;
  64. if (countnow >= expectCNTBegin && countnow < expectCNTEnd) {
  65. break;
  66. }
  67. }
  68. uint16_t v = prv_adc_get_value();
  69. return v;
  70. }