你的浏览器版本过低,可能导致网站不能正常访问!
为了你能正常使用网站功能,请使用这些浏览器。

【表格】STM32F103高级定时器OSSI/OSSR位与通道输出电平的关系

[复制链接]
zlk1214 发布时间:2017-12-26 19:14
RM0008手册中关于CHx和CHxN通道的输出电平与OSSI、OSSR、MOE、CCxE、CCxNE等位的关系表“Table 83. Output control bits for complementary OCx and OCxN channels with
break feature”完全就是错误的!
下面是实测出来的结果:
STM32F103VE TIM1
OSSI isn't cared
OSSR isn't cared when MOE=0
0000000XX: 0       0
0000001XX: OC1REF  ~OC1REF
0000010XX: OC1REF  ~OC1REF
0000011XX: 0       0
0000100XX: OC1REF  OC1REF
0000101XX: 0       1
0000110XX: 0       1
0000111XX: OC1REF  OC1REF
0001000XX: ~OC1REF ~OC1REF
0001001XX: 1       0
0001010XX: 1       0
0001011XX: ~OC1REF ~OC1REF
0001100XX: 1       1
0001101XX: ~OC1REF OC1REF
0001110XX: ~OC1REF OC1REF
0001111XX: 1       1
0010000XX: 0       0
0010001XX: 0       1
0010010XX: 1       0
0010011XX: 0       0
0010100XX: 0       0
0010101XX: 0       1
0010110XX: 0       1
0010111XX: 1       1
0011000XX: 0       0
0011001XX: 1       0
0011010XX: 1       0
0011011XX: 1       1
0011100XX: 1       1
0011101XX: 0       1
0011110XX: 1       0
0011111XX: 1       1
0100000XX: 0       0
0100001XX: 0       1
0100010XX: 1       0
0100011XX: 0       0
0100100XX: 0       0
0100101XX: 0       1
0100110XX: 0       1
0100111XX: 1       1
0101000XX: 0       0
0101001XX: 1       0
0101010XX: 1       0
0101011XX: 1       1
0101100XX: 1       1
0101101XX: 0       1
0101110XX: 1       0
0101111XX: 1       1
0110000XX: 0       0
0110001XX: 0       1
0110010XX: 1       0
0110011XX: 0       0
0110100XX: 0       0
0110101XX: 0       1
0110110XX: 0       1
0110111XX: 1       1
0111000XX: 0       0
0111001XX: 1       0
0111010XX: 1       0
0111011XX: 1       1
0111100XX: 1       1
0111101XX: 0       1
0111110XX: 1       0
0111111XX: 1       1
10000000X: 0       0
10000001X: 0       0
10000010X: 0       0
10000011X: 0       0
10000100X: 0       0
10000101X: 0       0
10000110X: 0       0
10000111X: 0       0
10001000X: 0       0
10001001X: 0       1
10001010X: 0       0
10001011X: 0       1
10001100X: 0       0
10001101X: 0       1
10001110X: 0       0
10001111X: 0       1
10010000X: 0       0
10010001X: 1       0
10010010X: 0       0
10010011X: 1       0
10010100X: 0       0
10010101X: 1       0
10010110X: 0       0
10010111X: 1       0
10011000X: 0       0
10011001X: 1       1
10011010X: 0       0
10011011X: 1       1
10011100X: 0       0
10011101X: 1       1
10011110X: 0       0
10011111X: 1       1
10100000X: 0       OC1REF
10100001X: 0       OC1REF
10100010X: 0       OC1REF
10100011X: 0       OC1REF
10100100X: 0       OC1REF
10100101X: 0       OC1REF
10100110X: 0       OC1REF
10100111X: 0       OC1REF
10101000X: 0       ~OC1REF
10101001X: 0       ~OC1REF
10101010X: 0       ~OC1REF
10101011X: 0       ~OC1REF
10101100X: 0       ~OC1REF
10101101X: 0       ~OC1REF
10101110X: 0       ~OC1REF
10101111X: 0       ~OC1REF
10110000X: 0       OC1REF
10110001X: 1       OC1REF
10110010X: 0       OC1REF
10110011X: 1       OC1REF
10110100X: 0       OC1REF
10110101X: 1       OC1REF
10110110X: 0       OC1REF
10110111X: 1       OC1REF
10111000X: 0       ~OC1REF
10111001X: 1       ~OC1REF
10111010X: 0       ~OC1REF
10111011X: 1       ~OC1REF
10111100X: 0       ~OC1REF
10111101X: 1       ~OC1REF
10111110X: 0       ~OC1REF
10111111X: 1       ~OC1REF
11000000X: OC1REF  0
11000001X: OC1REF  0
11000010X: OC1REF  0
11000011X: OC1REF  0
11000100X: OC1REF  0
11000101X: OC1REF  0
11000110X: OC1REF  0
11000111X: OC1REF  0
11001000X: OC1REF  0
11001001X: OC1REF  1
11001010X: OC1REF  0
11001011X: OC1REF  1
11001100X: OC1REF  0
11001101X: OC1REF  1
11001110X: OC1REF  0
11001111X: OC1REF  1
11010000X: ~OC1REF 0
11010001X: ~OC1REF 0
11010010X: ~OC1REF 0
11010011X: ~OC1REF 0
11010100X: ~OC1REF 0
11010101X: ~OC1REF 0
11010110X: ~OC1REF 0
11010111X: ~OC1REF 0
11011000X: ~OC1REF 0
11011001X: ~OC1REF 1
11011010X: ~OC1REF 0
11011011X: ~OC1REF 1
11011100X: ~OC1REF 0
11011101X: ~OC1REF 1
11011110X: ~OC1REF 0
11011111X: ~OC1REF 1
11100000X: OC1REF  ~OC1REF
11100001X: OC1REF  ~OC1REF
11100010X: OC1REF  ~OC1REF
11100011X: OC1REF  ~OC1REF
11100100X: OC1REF  ~OC1REF
11100101X: OC1REF  ~OC1REF
11100110X: OC1REF  ~OC1REF
11100111X: OC1REF  ~OC1REF
11101000X: OC1REF  OC1REF
11101001X: OC1REF  OC1REF
11101010X: OC1REF  OC1REF
11101011X: OC1REF  OC1REF
11101100X: OC1REF  OC1REF
11101101X: OC1REF  OC1REF
11101110X: OC1REF  OC1REF
11101111X: OC1REF  OC1REF
11110000X: ~OC1REF ~OC1REF
11110001X: ~OC1REF ~OC1REF
11110010X: ~OC1REF ~OC1REF
11110011X: ~OC1REF ~OC1REF
11110100X: ~OC1REF ~OC1REF
11110101X: ~OC1REF ~OC1REF
11110110X: ~OC1REF ~OC1REF
11110111X: ~OC1REF ~OC1REF
11111000X: ~OC1REF OC1REF
11111001X: ~OC1REF OC1REF
11111010X: ~OC1REF OC1REF
11111011X: ~OC1REF OC1REF
11111100X: ~OC1REF OC1REF
11111101X: ~OC1REF OC1REF
11111110X: ~OC1REF OC1REF
11111111X: ~OC1REF OC1REF
从左到右依次为MOE, CC1E, CC1NE, CC1P, CC1NP, OIS1, OIS1N, OSSR, OSSI:    CH1    CH1N
OC1REF表示正常输出电平, ~表示取反,X表示don't care

从表格中可以看到一个事实:OSSI位没有任何作用!
并且,当输出总开关MOE=0时,输出端也能输出PWM波形,并非一定就是输出无效态电平!

收藏 评论2 发布时间:2017-12-26 19:14

举报

2个回答
zlk1214 回答时间:2017-12-26 19:15:14
产生该表格所用的程序:
  1. #include <stdio.h>
  2. #include <stm32f10x.h>
  3. #include <string.h>

  4. #define _BV(n) (1 << (n))

  5. /* 01序列从右到左的顺序 */
  6. typedef enum
  7. {
  8.   OSSI, // 最右
  9.   OSSR,
  10.   OIS1N,
  11.   OIS1,
  12.   CC1NP,
  13.   CC1P,
  14.   CC1NE,
  15.   CC1E,
  16.   MOE, // 最左
  17.   MAXSTATE // 代表总位数
  18. } StateBits;

  19. uint8_t states[_BV(MAXSTATE)][2][2];

  20. int fputc(int ch, FILE *fp)
  21. {
  22.   if (fp == stdout)
  23.   {
  24.     if (ch == '\n')
  25.     {
  26.       while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
  27.       USART_SendData(UART5, '\r');
  28.     }
  29.     while (USART_GetFlagStatus(UART5, USART_FLAG_TXE) == RESET);
  30.     USART_SendData(UART5, ch);
  31.   }
  32.   return ch;
  33. }

  34. uint8_t read_pin(GPIO_TypeDef *GPIOx, uint16_t pin)
  35. {
  36.   uint8_t value = 0;
  37.   GPIO_InitTypeDef gpio;
  38.   
  39.   gpio.GPIO_Mode = GPIO_Mode_IPU;
  40.   gpio.GPIO_Pin = pin;
  41.   GPIO_Init(GPIOx, &gpio);
  42.   if (GPIO_ReadInputDataBit(GPIOx, pin) == Bit_SET)
  43.     value |= 1;
  44.   
  45.   gpio.GPIO_Mode = GPIO_Mode_IPD;
  46.   GPIO_Init(GPIOx, &gpio);
  47.   if (GPIO_ReadInputDataBit(GPIOx, pin) == Bit_SET)
  48.     value |= 2;
  49.   
  50.   if (value == 0)
  51.     return 0; // 两次都读到低电平
  52.   else if (value == 3)
  53.     return 1; // 两次都读到高电平
  54.   else if (value == 1)
  55.     return 2; // 若读到的电平和使用的上拉电阻一样, 则说明是高阻态
  56.   else
  57.   {
  58.     printf("read_pin error! value=%d\n", value);
  59.     while (1);
  60.   }
  61. }

  62. void check_all(void)
  63. {
  64.   uint16_t value = 0;
  65.   TIM_BDTRInitTypeDef tim_bdtr;
  66.   TIM_OCInitTypeDef tim_oc;
  67.   TIM_TimeBaseInitTypeDef tim;
  68.   
  69.   TIM_TimeBaseStructInit(&tim);
  70.   tim.TIM_Period = 899;
  71.   tim.TIM_Prescaler = 71;
  72.   TIM_TimeBaseInit(TIM1, &tim);
  73.   TIM_Cmd(TIM1, ENABLE);
  74.   
  75.   tim_oc.TIM_OCMode = TIM_OCMode_PWM1;
  76.   tim_oc.TIM_Pulse = 499;
  77.   TIM_BDTRStructInit(&tim_bdtr);
  78.   while (value < _BV(MAXSTATE))
  79.   {
  80.     if (TIM_GetFlagStatus(TIM1, TIM_FLAG_Update) == SET)
  81.     {
  82.       /* 匹配前 */
  83.       TIM_ClearFlag(TIM1, TIM_FLAG_Update);
  84.       
  85.       tim_bdtr.TIM_OSSIState = (value & _BV(OSSI)) ? TIM_OSSIState_Enable : TIM_OSSIState_Disable;
  86.       tim_bdtr.TIM_OSSRState = (value & _BV(OSSR)) ? TIM_OSSRState_Enable : TIM_OSSRState_Disable;
  87.       TIM_BDTRConfig(TIM1, &tim_bdtr);
  88.       
  89.       tim_oc.TIM_OCIdleState = (value & _BV(OIS1)) ? TIM_OCIdleState_Set : TIM_OCIdleState_Reset;
  90.       tim_oc.TIM_OCNIdleState = (value & _BV(OIS1N)) ? TIM_OCNIdleState_Set : TIM_OCNIdleState_Reset;
  91.       tim_oc.TIM_OCNPolarity = (value & _BV(CC1NP)) ? TIM_OCNPolarity_Low : TIM_OCNPolarity_High;
  92.       tim_oc.TIM_OCPolarity = (value & _BV(CC1P)) ? TIM_OCPolarity_Low : TIM_OCPolarity_High;
  93.       tim_oc.TIM_OutputNState = (value & _BV(CC1NE)) ? TIM_OutputNState_Enable : TIM_OutputNState_Disable;
  94.       tim_oc.TIM_OutputState = (value & _BV(CC1E)) ? TIM_OutputState_Enable : TIM_OutputState_Disable;
  95.       TIM_OC1Init(TIM1, &tim_oc);
  96.       
  97.       TIM_CtrlPWMOutputs(TIM1, (value & _BV(MOE)) ? ENABLE : DISABLE);
  98.       
  99.       states[value][0][0] = read_pin(GPIOE, GPIO_Pin_0); // TIM1_CH1匹配前电平
  100.       states[value][1][0] = read_pin(GPIOE, GPIO_Pin_1); // TIM1_CH1N匹配前电平
  101.     }
  102.     else if (TIM_GetFlagStatus(TIM1, TIM_FLAG_CC1) == SET)
  103.     {
  104.       /* 匹配后 */
  105.       TIM_ClearFlag(TIM1, TIM_FLAG_CC1);
  106.       states[value][0][1] = read_pin(GPIOE, GPIO_Pin_0); // TIM1_CH1匹配后电平
  107.       states[value][1][1] = read_pin(GPIOE, GPIO_Pin_1); // TIM1_CH1N匹配后电平
  108.       value++;
  109.     }
  110.   }
  111.   TIM_Cmd(TIM1, DISABLE);
  112. }

  113. const char *value2str(uint16_t value)
  114. {
  115.   static char buf[20];
  116.   uint8_t i;
  117.   uint8_t j = 0;
  118.   uint16_t temp = value;
  119.   for (i = MAXSTATE - 1; i < MAXSTATE; i--)
  120.   {
  121.     if (i == OSSI || (i == OSSR && (value & _BV(MOE)) == 0))
  122.       buf[j] = 'X';
  123.     else if (temp & _BV(MAXSTATE - 1))
  124.       buf[j] = '1';
  125.     else
  126.       buf[j] = '0';
  127.     temp <<= 1;
  128.     j++;
  129.   }
  130.   buf[j] = '\0';
  131.   return buf;
  132. }

  133. void print_all(void)
  134. {
  135.   uint8_t i;
  136.   uint16_t value;
  137.   
  138.   // 结论1: OSSI位无意义
  139.   for (value = 0; value < _BV(MAXSTATE); value++)
  140.   {
  141.     if ((value & _BV(OSSI)) == 0)
  142.     {
  143.       if (memcmp(states[value], states[value | _BV(OSSI)], 4) != 0)
  144.         break;
  145.     }
  146.   }
  147.   if (value == _BV(MAXSTATE))
  148.     printf("OSSI isn't cared\n");
  149.   else
  150.   {
  151.     printf("OSSI is cared\n");
  152.     return;
  153.   }
  154.   
  155.   // 结论2: 当MOE=0时, OSSR位无意义
  156.   for (value = 0; value < _BV(MAXSTATE); value++)
  157.   {
  158.     if ((value & _BV(MOE)) == 0)
  159.     {
  160.       if (memcmp(states[value], states[value | _BV(OSSR)], 4) != 0)
  161.         break;
  162.     }
  163.   }
  164.   if (value == _BV(MAXSTATE))
  165.     printf("OSSR isn't cared when MOE=0\n");
  166.   else
  167.   {
  168.     printf("OSSR is cared when MOE=0\n");
  169.     return;
  170.   }
  171.   
  172.   // 当上述结论成立时, 输出所有配置情况
  173.   for (value = 0; value < _BV(MAXSTATE); value++)
  174.   {
  175.     if (value & _BV(OSSI))
  176.       continue; // 忽略OSSI=1的情况
  177.     if ((value & _BV(MOE)) == 0 && (value & _BV(OSSR)))
  178.       continue; // 忽略MOE=0且OSSR=1的情况
  179.    
  180.     printf("%s:", value2str(value));
  181.     for (i = 0; i < 2; i++)
  182.     {
  183.       if (states[value][i][0] == 0 && states[value][i][1] == 0)
  184.         printf(" 0      ");
  185.       else if (states[value][i][0] == 0 && states[value][i][1] == 1)
  186.         printf(" ~OC1REF");
  187.       else if (states[value][i][0] == 1 && states[value][i][1] == 0)
  188.         printf(" OC1REF ");
  189.       else if (states[value][i][0] == 1 && states[value][i][1] == 1)
  190.         printf(" 1      ");
  191.       else
  192.         printf(" ?%d%d    ", states[value][i][0], states[value][i][1]);
  193.     }
  194.     printf("\n");
  195.   }
  196. }

  197. int main(void)
  198. {
  199.   GPIO_InitTypeDef gpio;
  200.   USART_InitTypeDef usart;
  201.   
  202.   RCC_APB1PeriphClockCmd(RCC_APB1Periph_UART5, ENABLE);
  203.   RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA | RCC_APB2Periph_GPIOB | RCC_APB2Periph_GPIOC | RCC_APB2Periph_GPIOD | RCC_APB2Periph_GPIOE | RCC_APB2Periph_TIM1, ENABLE);
  204.   DBGMCU_Config(DBGMCU_TIM1_STOP, ENABLE); // 调试程序时TIM1暂停计数
  205.   
  206.   // TIM1_CH1(PA8)接到PE0上采集
  207.   gpio.GPIO_Mode = GPIO_Mode_AF_PP;
  208.   gpio.GPIO_Pin = GPIO_Pin_8;
  209.   gpio.GPIO_Speed = GPIO_Speed_50MHz;
  210.   GPIO_Init(GPIOA, &gpio);
  211.   
  212.   // TIM1_CH1N(PB13)接到PE1上采集
  213.   gpio.GPIO_Pin = GPIO_Pin_13;
  214.   GPIO_Init(GPIOB, &gpio);
  215.   
  216.   // UART5_TX(PC12)
  217.   gpio.GPIO_Pin = GPIO_Pin_12;
  218.   GPIO_Init(GPIOC, &gpio);
  219.   // UART5_RX(PD2)默认就是浮空输入, 无需配置
  220.   
  221.   USART_StructInit(&usart);
  222.   usart.USART_BaudRate = 115200;
  223.   USART_Init(UART5, &usart);
  224.   USART_Cmd(UART5, ENABLE);
  225.   printf("STM32F103VE TIM1\n");
  226.   
  227.   check_all();
  228.   print_all();
  229.   while (1);
  230. }
复制代码


zlk1214 回答时间:2018-1-5 13:34:45
这是Excel表格文件,可以在其中筛选查看

STM32F103高级定时器OSSI_OSSR位与通道输出电平的关系表.rar

下载

12.47 KB, 下载次数: 9

做成了Excel表格

所属标签

相似分享

官网相关资源

关于
我们是谁
投资者关系
意法半导体可持续发展举措
创新与技术
意法半导体官网
联系我们
联系ST分支机构
寻找销售人员和分销渠道
社区
媒体中心
活动与培训
隐私策略
隐私策略
Cookies管理
行使您的权利
官方最新发布
STM32N6 AI生态系统
STM32MCU,MPU高性能GUI
ST ACEPACK电源模块
意法半导体生物传感器
STM32Cube扩展软件包
关注我们
st-img 微信公众号
st-img 手机版