ch32v003逻辑分析仪波形

只是一个普通的翻转

  

/********************************** (C) COPYRIGHT *******************************
 * File Name          : main.c
 * Author             : WCH
 * Version            : V1.0.0
 * Date               : 2023/12/22
 * Description        : Main program body.
 *********************************************************************************
 * Copyright (c) 2021 Nanjing Qinheng Microelectronics Co., Ltd.
 * Attention: This software (modified or not) and binary are used for
 * microcontroller manufactured by Nanjing Qinheng Microelectronics.
 *******************************************************************************/
/*
 *@Note
 *GPIO routine:
 *PD0 push-pull output.
 *
*/
#include "debug.h"
/* Global define */
/* Global Variable */
/*********************************************************************
 * @fn      GPIO_Toggle_INIT
 *
 * @brief   Initializes GPIOA.0
 *
 * @return  none
 */
void GPIO_Toggle_INIT(void)
{
    GPIO_InitTypeDef GPIO_InitStructure = {0};
    RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
    GPIO_InitStructure.GPIO_Pin = GPIO_Pin_1;
    GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP;
    GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz;
    GPIO_Init(GPIOC, &GPIO_InitStructure);
}
/*********************************************************************
 * @fn      main
 *
 * @brief   Main program.
 *
 * @return  none
 */
int main(void)
{
    u8 i = 0;
    NVIC_PriorityGroupConfig(NVIC_PriorityGroup_1);
    SystemCoreClockUpdate();
    Delay_Init();
#if (SDI_PRINT == SDI_PR_OPEN)
    SDI_Printf_Enable();
#else
    USART_Printf_Init(115200);
#endif
    printf("SystemClk:%d\r\n", SystemCoreClock);
    printf( "ChipID:%08x\r\n", DBGMCU_GetCHIPID() );
    printf("GPIO Toggle TEST\r\n");
    GPIO_Toggle_INIT();
    while(1)
    {
        Delay_Ms(250);
        GPIO_WriteBit(GPIOC, GPIO_Pin_1, (i == 0) ? (i = Bit_SET) : (i = Bit_RESET));
    }
}

ms级看还正常,

image.png

但是us级,上升沿这个为什么要多一个这出来,每个上升沿都有,小白的我 ds18b20 us控制异常,是不是要加外围电阻电容呀image.png

您好,我这边测试us级的翻转也是没问题的,你可以提高逻辑分析仪采样率试一下。正常若使用DS18B20模块,直接连应该是没问题的。若需要可以留个邮箱,发你个DS18B20的程序参考一下。后续若有问题,也可以通过邮箱(lzs@wch.cn)和我沟通。


代码我从stm32f103写好能跑,后面又放air001上跑,都ok,代码我感觉应该没啥问题,哎,中午的代码和逻辑分析仪啥都没动,us级现在没问题了,奇怪,output切input又有问题了,邮箱地址:个人信息保护,已隐藏 ,先感谢大佬发程序参考。


您好,已发邮箱,请查收


这大概率不是芯片问题,而是接线和逻辑分析仪问题。

截图里ms级信号明显问题一样,两个上升沿有三个像素,解码的reset也断开了。


这种问题大概率是信号在边沿处引发的振铃。提高逻辑分析仪采样率是没用的,想要观察振铃现象,最好用示波器看波形,或者Saleae Logic一类带模拟输入的逻辑分析仪观察。振铃在使用长杜邦线一类比较随便的连接时尤其严重。


解决办法可以想wch-link-E一样,在线上串个电阻,或者把 GPIO_Speed_50MHz 改小试试。



#include "ds18b20.h"
float Temperature = 0;
uint8_t Temp_byte1, Temp_byte2;
uint16_t TEMP;

void Set_Pin_Output(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_Out_PP;
	GPIO_InitStruct.GPIO_Speed = GPIO_Speed_50MHz;
	GPIO_Init(GPIOx, &GPIO_InitStruct);
}

void Set_Pin_Input(GPIO_TypeDef *GPIOx, uint16_t GPIO_Pin) {
	GPIO_InitTypeDef GPIO_InitStruct = { 0 };
	RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOC, ENABLE);
	GPIO_InitStruct.GPIO_Pin = GPIO_Pin;
	GPIO_InitStruct.GPIO_Mode = GPIO_Mode_IPU;
	GPIO_Init(GPIOx, &GPIO_InitStruct);
}

uint8_t DS18B20_Presence(void) {
	uint8_t pulse_time = 0;

	/* 主机设置为上拉输入 */
	Set_Pin_Input(DS18B20_PORT, DS18B20_PIN);

	/* 等待存在脉冲的到来,存在脉冲为一个60~240us的低电平信号
	 *   如果存在脉冲没有来则做超时处理,从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲
	 */
	while (GPIO_ReadInputDataBit( DS18B20_PORT, DS18B20_PIN) && pulse_time < 100) {
		pulse_time++;
		Delay_Us(1);
	}
	/* 经过100us后,存在脉冲都还没有到来*/
	if (pulse_time >= 100)
		return 1;
	else
		pulse_time = 0;

	/* 存在脉冲到来,且存在的时间不能超过240us */
	while (!GPIO_ReadInputDataBit( DS18B20_PORT, DS18B20_PIN)
			&& pulse_time < 240) {
		pulse_time++;
		Delay_Us(1);
	}
	if (pulse_time >= 240)
		return 1;
	else
		return 0;
}
uint8_t DS18B20_Init(void) {
	Set_Pin_Output(DS18B20_PORT, DS18B20_PIN);

	GPIO_SetBits( DS18B20_PORT, DS18B20_PIN);

	DS18B20_Rst();

	return DS18B20_Presence();
}
void DS18B20_Rst(void) {
	/* 主机设置为推挽输出 */
	Set_Pin_Output(DS18B20_PORT, DS18B20_PIN);

	GPIO_ResetBits( DS18B20_PORT, DS18B20_PIN);
	/* 主机至少产生480us的低电平复位信号 */
	Delay_Us(750);

	/* 主机在产生复位信号后,需将总线拉高 */
	GPIO_SetBits( DS18B20_PORT, DS18B20_PIN);

	/*从机接收到主机的复位信号后,会在15~60us后给主机发一个存在脉冲*/
	Delay_Us(15);
}



/*
   * 从DS18B20读取一个bit
 */
static uint8_t DS18B20_ReadBit(void)
{
    uint8_t dat;

    /* 读0和读1的时间至少要大于60us */
    Set_Pin_Output(DS18B20_PORT, DS18B20_PIN);
    /* 读时间的起始:必须由主机产生 >1us <15us 的低电平信号 */
    GPIO_ResetBits( DS18B20_PORT, DS18B20_PIN);;
    Delay_Us(10);

    /* 设置成输入,释放总线,由外部上拉电阻将总线拉高 */
   Set_Pin_Input(DS18B20_PORT, DS18B20_PIN);
    //Delay_Us(2);

    if( GPIO_ReadInputDataBit( DS18B20_PORT, DS18B20_PIN) == SET )
        dat = 1;
    else
        dat = 0;

    /* 这个延时参数请参考时序图 */
    Delay_Us(45);

    return dat;
}


/*
 * 从DS18B20读一个字节,低位先行
 */
static uint8_t DS18B20_ReadByte(void)
{
    uint8_t i, j, dat = 0;

    for(i=0; i<8; i++)
    {
        j = DS18B20_ReadBit();
        dat = (dat) | (j<>1;
        /* 写0和写1的时间至少要大于60us */
        if (testb)
        {
            GPIO_ResetBits( DS18B20_PORT, DS18B20_PIN);;
            /* 1us < 这个延时 < 15us */
            Delay_Us(8);

            GPIO_SetBits( DS18B20_PORT, DS18B20_PIN);;
            Delay_Us(58);
        }
        else
        {
            GPIO_ResetBits( DS18B20_PORT, DS18B20_PIN);;
            /* 60us < Tx 0 < 120us */
            Delay_Us(70);

            GPIO_SetBits( DS18B20_PORT, DS18B20_PIN);;
            /* 1us < Trec(恢复时间) < 无穷大*/
            Delay_Us(2);
        }
    }
}

/**
 * @brief  跳过匹配 DS18B20 ROM
 * @param  无
 * @retval 无
 */
static void DS18B20_SkipRom ( void )
{
   DS18B20_Rst();

   DS18B20_Presence();

   DS18B20_WriteByte(0XCC);        /* 跳过 ROM */
}


/**
 * @brief  执行匹配 DS18B20 ROM
 * @param  无
 * @retval 无
 */
static void DS18B20_MatchRom ( void )
{
   DS18B20_Rst();

   DS18B20_Presence();

   DS18B20_WriteByte(0X55);        /* 匹配 ROM */
}


/*
* 存储的温度是16 位的带符号扩展的二进制补码形式
* 当工作在12位分辨率时,其中5个符号位,7个整数位,4个小数位
*
*         |---------整数----------|-----小数 分辨率 1/(2^4)=0.0625----|
* 低字节  | 2^3 | 2^2 | 2^1 | 2^0 | 2^(-1) | 2^(-2) | 2^(-3) | 2^(-4) |
*
*
*         |-----符号位:0->正  1->负-------|-----------整数-----------|
* 高字节  |  s  |  s  |  s  |  s  |    s   |   2^6  |   2^5  |   2^4  |
*
*
* 温度 = 符号位 + 整数 + 小数*0.0625
*/
/**
 * @brief  在跳过匹配 ROM 情况下获取 DS18B20 温度值
 * @param  无
 * @retval 温度值
 */
float DS18B20_GetTemp_SkipRom ( void )
{
   uint8_t tpmsb, tplsb;
   short s_tem;
   float f_tem;

   DS18B20_SkipRom ();
   DS18B20_WriteByte(0X44);              /* 开始转换 */

   DS18B20_SkipRom ();
   DS18B20_WriteByte(0XBE);              /* 读温度值 */

   tplsb = DS18B20_ReadByte();
   tpmsb = DS18B20_ReadByte();

   s_tem = tpmsb<<8;
   s_tem = s_tem | tplsb;

   if( s_tem < 0 )     /* 负温度 */
       f_tem = (~s_tem+1) * 0.0625;
   else
       f_tem = s_tem * 0.0625;

   return f_tem;
}


/**
 * @brief  在匹配 ROM 情况下获取 DS18B20 温度值
 * @param  ds18b20_id:用于存放 DS18B20 序列号的数组的首地址
 * @retval 无
 */
void DS18B20_ReadId ( uint8_t * ds18b20_id )
{
   uint8_t uc;

   DS18B20_WriteByte(0x33);       //读取序列号

   for ( uc = 0; uc < 8; uc ++ )
     ds18b20_id [ uc ] = DS18B20_ReadByte();
}


/**
 * @brief  在匹配 ROM 情况下获取 DS18B20 温度值
 * @param  ds18b20_id:存放 DS18B20 序列号的数组的首地址
 * @retval 温度值
 */
float DS18B20_GetTemp_MatchRom ( uint8_t * ds18b20_id )
{
   uint8_t tpmsb, tplsb, i;
   short s_tem;
   float f_tem;


   DS18B20_MatchRom ();            //匹配ROM

   for(i=0;i<8;i++)
       DS18B20_WriteByte ( ds18b20_id [ i ] );

   DS18B20_WriteByte(0X44);        /* 开始转换 */


   DS18B20_MatchRom ();            //匹配ROM

   for(i=0;i<8;i++)
       DS18B20_WriteByte ( ds18b20_id [ i ] );

   DS18B20_WriteByte(0XBE);        /* 读温度值 */

   tplsb = DS18B20_ReadByte();
   tpmsb = DS18B20_ReadByte();


   s_tem = tpmsb<<8;
   s_tem = s_tem | tplsb;

   if( s_tem < 0 )     /* 负温度 */
       f_tem = (~s_tem+1) * 0.0625;
   else
       f_tem = s_tem * 0.0625;

   return f_tem;
}

代码贴这里给有需要的人


5楼说的振铃现象现象,有时候有,有时候没有,现在温度能读了,感觉波型跟网上的不太一样
image.png


image.png


只有登录才能回复,可以选择微信账号登录