- 2025-01-18
-
发表了主题帖:
【KW41Z开发板测评】②PWM输出呼吸灯
承接上期的【KW41Z开发板测评】①开箱及搭建环境并点灯帖子,使用NXP官方的MCUXpresso IDE很容易导出体验官方的参考例程。
这期借助“frdmkw41z_driver_examples_tpm_simple_pwm”参考例程来实现呼吸灯效果。官方的例程是通过串口给开发板发“0”~“9”来手动调节占空比,从而使RGB灯的蓝色管脚输出固定值的占空比,调节灯的亮度。
根据RGB灯部分的原理图,可知控制RGB灯蓝色输出的信号脚为PTA18,复用为TPM2_CH0通道,这里简单分享一下。
根据数据手册可知,PTA18复用关系。
修改部分代码,工程源码关键部分展示如下:
pin_mux.c
#include "fsl_common.h"
#include "fsl_port.h"
#include "pin_mux.h"
#define PIN6_IDX 6u /*!< Pin number for pin 6 in a port */
#define PIN7_IDX 7u /*!< Pin number for pin 7 in a port */
#define PIN18_IDX 18u /*!< Pin number for pin 18 in a port */
#define SOPT4_TPM2CH0SRC_TPM 0x00u /*!< TPM2 Channel 0 Input Capture Source Select: TPM2_CH0 signal */
#define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!< LPUART0 Receive Data Source Select: LPUART_RX pin */
/*
* TEXT BELOW IS USED AS SETTING FOR THE PINS TOOL *****************************
BOARD_InitPins:
- options: {coreID: singlecore, enableClock: 'true'}
- pin_list:
- {pin_num: '42', peripheral: LPUART0, signal: RX, pin_signal: TSI0_CH2/PTC6/LLWU_P14/XTAL_OUT_EN/I2C1_SCL/UART0_RX/TPM2_CH0/BSM_FRAME}
- {pin_num: '43', peripheral: LPUART0, signal: TX, pin_signal: TSI0_CH3/PTC7/LLWU_P15/SPI0_PCS2/I2C1_SDA/UART0_TX/TPM2_CH1/BSM_DATA}
- {pin_num: '6', peripheral: TPM2, signal: 'CH, 0', pin_signal: TSI0_CH12/PTA18/LLWU_P6/SPI1_SCK/TPM2_CH0}
* BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR THE PINS TOOL ***
*/
/*FUNCTION**********************************************************************
*
* Function Name : BOARD_InitPins
* Description : Configures pin routing and optionally pin electrical features.
*
*END**************************************************************************/
void BOARD_InitPins(void) {
CLOCK_EnableClock(kCLOCK_PortA); /* Port A Clock Gate Control: Clock enabled */
CLOCK_EnableClock(kCLOCK_PortC); /* Port C Clock Gate Control: Clock enabled */
PORT_SetPinMux(PORTA, PIN18_IDX, kPORT_MuxAlt5); /* PORTA18 (pin 6) is configured as TPM2_CH0 */
PORT_SetPinMux(PORTC, PIN6_IDX, kPORT_MuxAlt4); /* PORTC6 (pin 42) is configured as UART0_RX */
PORT_SetPinMux(PORTC, PIN7_IDX, kPORT_MuxAlt4); /* PORTC7 (pin 43) is configured as UART0_TX */
SIM->SOPT4 = ((SIM->SOPT4 &
(~(SIM_SOPT4_TPM2CH0SRC_MASK))) /* Mask bits to zero which are setting */
| SIM_SOPT4_TPM2CH0SRC(SOPT4_TPM2CH0SRC_TPM) /* TPM2 Channel 0 Input Capture Source Select: TPM2_CH0 signal */
);
SIM->SOPT5 = ((SIM->SOPT5 &
(~(SIM_SOPT5_LPUART0RXSRC_MASK))) /* Mask bits to zero which are setting */
| SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX) /* LPUART0 Receive Data Source Select: LPUART_RX pin */
);
}
tpm_simple_pwm.c
#include "fsl_debug_console.h"
#include "board.h"
#include "fsl_tpm.h"
#include "pin_mux.h"
/*******************************************************************************
* Definitions
******************************************************************************/
#define BOARD_TPM_BASEADDR TPM2
#define BOARD_TPM_CHANNEL 0U
/* Interrupt to enable and flag to read; depends on the TPM channel used */
#define TPM_CHANNEL_INTERRUPT_ENABLE kTPM_Chnl0InterruptEnable
#define TPM_CHANNEL_FLAG kTPM_Chnl0Flag
/* Interrupt number and interrupt handler for the TPM instance used */
#define TPM_INTERRUPT_NUMBER TPM2_IRQn
#define TPM_LED_HANDLER TPM2_IRQHandler
/* Get source clock for TPM driver */
#define TPM_SOURCE_CLOCK CLOCK_GetFreq(kCLOCK_McgFllClk)
/*******************************************************************************
* Variables
******************************************************************************/
volatile bool brightnessUp = true; /* Indicate LED is brighter or dimmer */
volatile uint8_t updatedDutycycle = 10U;
volatile uint8_t getCharValue = 0U;
volatile uint32_t g_systickCounter;
uint8_t dutyCycle = 0;
uint8_t var = 0;
/*******************************************************************************
* Code
******************************************************************************/
void SysTick_Handler(void)
{
if (g_systickCounter != 0U)
{
g_systickCounter--;
}
}
void SysTick_DelayTicks(uint32_t n)
{
g_systickCounter = n;
while (g_systickCounter != 0U)
{
}
}
/*!
* [url=home.php?mod=space&uid=159083]@brief[/url] Main function
*/
int main(void)
{
tpm_config_t tpmInfo;
tpm_chnl_pwm_signal_param_t tpmParam;
tpm_pwm_level_select_t pwmLevel = kTPM_LowTrue;
/* Configure tpm params with frequency 24kHZ */
tpmParam.chnlNumber = (tpm_chnl_t)BOARD_TPM_CHANNEL;
tpmParam.level = pwmLevel;
tpmParam.dutyCyclePercent = updatedDutycycle;
/* Board pin, clock, debug console init */
BOARD_InitPins();
BOARD_BootClockRUN();
BOARD_InitDebugConsole();
/* Select the clock source for the TPM counter as MCGPLLCLK */
CLOCK_SetTpmClock(1U);
/* Set systick reload value to generate 1ms interrupt */
if (SysTick_Config(SystemCoreClock / 1000U))
{
while (1)
{
}
}
TPM_GetDefaultConfig(&tpmInfo);
/* Initialize TPM module */
TPM_Init(BOARD_TPM_BASEADDR, &tpmInfo);
TPM_SetupPwm(BOARD_TPM_BASEADDR, &tpmParam, 1U, kTPM_CenterAlignedPwm, 24000U, TPM_SOURCE_CLOCK);
TPM_StartTimer(BOARD_TPM_BASEADDR, kTPM_SystemClock);
while (1)
{
if(var == 0)
{
dutyCycle+=10;
}
else if(var == 1)
{
dutyCycle-=10;
}
/* Disable channel output before updating the dutycycle */
TPM_UpdateChnlEdgeLevelSelect(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, 0U);
/* Update PWM duty cycle */
TPM_UpdatePwmDutycycle(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, kTPM_CenterAlignedPwm,
dutyCycle);
/* Start channel output with updated dutycycle */
TPM_UpdateChnlEdgeLevelSelect(BOARD_TPM_BASEADDR, (tpm_chnl_t)BOARD_TPM_CHANNEL, pwmLevel);
SysTick_DelayTicks(60U);
if(dutyCycle > 90)
var = 1;
else if(dutyCycle < 10)
var = 0;
}
}
然后Debug,将编译完的固件程序烧写到开发板中,运行程序,呈现呼吸道效果,见如下视频。
[localvideo]6a152fadf75f0a3e1a9a77b07faac7df[/localvideo]
- 2025-01-17
-
回复了主题帖:
EEWorld 2024年度人物:感恩相伴,共赴新程,携手努力!
2025,携手共进,风雨无阻,再创佳绩!
- 2025-01-14
-
发表了主题帖:
【KW41Z开发板测评】①开箱及搭建环境并点灯
本帖最后由 yin_wu_qing 于 2025-1-14 22:00 编辑
一、概况
周日收到了年终回炉的“NXP FREEDOM DEVELOPMENT BOARD KW41Z”开发板,第一时间去到:MCUXpresso SDK 构建工具网站,登录NXP个人账号,进行SDK的构建、下载。通过面向Kinetis® KW41Z/31Z/21Z MCU的Freedom开发套件网址获取相关资料,FRDM-KW41Z板是一款支持无线多协议的开发板,主干框图如下:
二、开箱
收到的包裹中只用空气袋夹带着这块开发板,并没有microUSB数据线与BLE调试工具,不过这也并不影响后续的评测使用,空气袋包裹得还算比较严实,开发板正面干净,看上去有诸多跳线帽,还有外接天线的接口。
开发板背面有提供纽扣电池座,应用在低功耗场景,纽扣电池可让开发板进入到低功耗工作模式下持续供电。两旁的长长插针是正面的排座过孔延续。
将开发板上电检测一下,毕竟从包裹中拿出时,背面的插针有“东倒西歪”的。使用以前比较流行的MicroUSB数据线给板子上电,简单按键测试了下LED,功能正常。
三、搭建环境
从“MCUXpresso SDK构建工具”网页上获取关于KW41Z板的SDK时可知,该SDK导出只支持MCUXpresso IDE与IAR,并不支持MDK,因而笔者导出SDK时选择了MCUXpresso IDE,官方的工具导入工程也是非常方便。在IDE的左下栏中导入构建并下载好的SDK,这里建议不用解压,直接导入zip文件即可install。
接下来,傻瓜式选择“下一步”即可完成,然后import SDK中的工程示例。
这里笔者选择点灯例程
点击菜单栏下的“锤子”图标,进行工程的编译。
然后将编译好的程序下载到开发板中,由于该板集成了JLink调试器,只需要一根MicroUSB数据线即可完成下载、调试。
四、点灯效果
这里的例程,只是对GPIOC01管脚输出,即RGB灯的red红色点亮。程序解读,给GPIOC01输出低电平则红灯亮,输出高电平则红灯灭,效果如下:
[localvideo]bf9892d6d8413ae5d7ee0cae38fc69e8[/localvideo]
- 2025-01-10
-
回复了主题帖:
【回顾2024,展望2025】新年抢楼活动来啦!
立一个新年Flag,身体健健康康,早睡早起,告别亚健康。
- 2025-01-08
-
加入了学习《Follow me 第二季第3期成果视频》,观看 成果展示
-
回复了主题帖:
【测评入围名单(最后1批)】年终回炉:FPGA、AI、高性能MCU、书籍等65个测品邀你来~
个人信息确认无误,确认可以完成评测计划。
- 2024-06-30
-
回复了主题帖:
免费申请 | 最新一代树莓派(Raspberry Pi 5)!
积极支持一下活动!好活动!
- 2024-05-18
-
发表了主题帖:
《python编程快速上手》第5篇:python之字典和结构化数据
“字典”是许多值的集合,但不像列表的索引,字典的索引可以使用许多不同的数据类型,不只是整数。字典的索引被称为“键”,键及其关联的值称为“键-值对”。字典中的项是不排序的,下面就字典与列表差异展开话题。
尽管字典是不排序的,但可以用任意值作为键,这一点让开发人员能够用强大的方式来组织数据。假定你希望程序保存你朋友的生日数据,就可以使用一个字典,用名字作为键,用生日作为值。在Mu编辑工具中,新建一个.py文件,并在编辑器窗口输入以下代码,完成编辑后运行、测试。
birthdays = {'Aloy':'Apr 5','Bob':'Dec 15','Carol':'Mar 18'}
while True:
print('Enter a name:(blank to quit)')
name = input()
if name == '':
break
if name in birthdays:
print(birthdays[name] + 'is the birthday of' + name)
else:
print('I do not have birthday information for '+ name)
print('What is their birthday?')
bday = input()
birthdays[name] = bday
print('Birthday database updated.')
运行后,测试效果如下:
由代码可知,创建了一个初始的字典,将它保存在birthdays。用if name in birthdays中的in关键字,可以查看输入的名字是否作为键存在于字典中,就像查看列表一样。如果该名字在字典中,那么就可以用birthdays[]来访问关联的值。如果不存在,则可以用同样的"birthdays[]=name"方式来赋值操作添加到字典中。
字典中有3个方法,分别对应与字典的键、值和键-值对,即keys()、values()和items()方法。这些方法返回的值并不是真正的列表,它们不能被修改,没有append()方法。利用keys()、values()和items()方法,循环分别可以迭代键、值和键-值对。items()方法返回的是dict_items值包含的是键和值的元组。
以上并不会返回得到真正的列表,如果想通过这些方法得到一个真正的列表,就要把类似列表的返回值传递给list()函数。
跟列表一样,in或not in操作符可以检查值是否存在与列表中,也可以利用这些操作符,检查某个键或值是否存在于字典中。
访问一个键的值之前,必须通过检查该键是否存在于字典中,才能合法访问,这显得很是麻烦,字典中有提供一个get()方法,有带两个参数,分别为要取得其值的键,以及当键不存在时返回的备用值。
在字典中常常需要将某个键设置一个默认值,当该键没有任何值时使用它需要重新设定,setdefault()方法提供了一种方法,可以在一行中完成这样的设置需求,该方法第一个参数是要检查的键,第二个参数是当该键不存在时要设置的值,如果该键确实存在,那么setdefault()方法就会返回键的值,效果如下交互环境。
setdefault()方法是一个很好的快捷方式,可以确保有一个键存在,下面的一个小程序可以诠释,轻松实现计算一个字符串中每个字符出现的次数。在Mu工具的编辑窗口输入以下代码,保存后运行即可输出结果。
message = 'It was a bright cold day in April, and the clocks were striking thirteen.'
count = {}
for character in message:
count.setdefault(character, 0)
count[character] = count[character] + 1
print(count)
运行输出的结果如下:
{'I': 1}
{'I': 1, 't': 1}
{'I': 1, 't': 1, ' ': 1}
{'I': 1, 't': 1, ' ': 1, 'w': 1}
{'I': 1, 't': 1, ' ': 1, 'w': 1, 'a': 1}
{'I': 1, 't': 1, ' ': 1, 'w': 1, 'a': 1, 's': 1}
{'I': 1, 't': 1, ' ': 2, 'w': 1, 'a': 1, 's': 1}
{'I': 1, 't': 1, ' ': 2, 'w': 1, 'a': 2, 's': 1}
{'I': 1, 't': 1, ' ': 3, 'w': 1, 'a': 2, 's': 1}
{'I': 1, 't': 1, ' ': 3, 'w': 1, 'a': 2, 's': 1, 'b': 1}
{'I': 1, 't': 1, ' ': 3, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1}
{'I': 1, 't': 1, ' ': 3, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1}
{'I': 1, 't': 1, ' ': 3, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1}
{'I': 1, 't': 1, ' ': 3, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1}
{'I': 1, 't': 2, ' ': 3, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1}
{'I': 1, 't': 2, ' ': 4, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1}
{'I': 1, 't': 2, ' ': 4, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1}
{'I': 1, 't': 2, ' ': 4, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1}
{'I': 1, 't': 2, ' ': 4, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1}
{'I': 1, 't': 2, ' ': 4, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 1}
{'I': 1, 't': 2, ' ': 5, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 1}
{'I': 1, 't': 2, ' ': 5, 'w': 1, 'a': 2, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2}
{'I': 1, 't': 2, ' ': 5, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2}
{'I': 1, 't': 2, ' ': 5, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1}
{'I': 1, 't': 2, ' ': 6, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 1, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1}
{'I': 1, 't': 2, ' ': 6, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 2, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1}
{'I': 1, 't': 2, ' ': 6, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 2, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1, 'n': 1}
{'I': 1, 't': 2, ' ': 7, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 2, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1, 'n': 1}
{'I': 1, 't': 2, ' ': 7, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 2, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1, 'n': 1, 'A': 1}
{'I': 1, 't': 2, ' ': 7, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 1, 'i': 2, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1, 'n': 1, 'A': 1, 'p': 1}
{'I': 1, 't': 2, ' ': 7, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 2, 'i': 2, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1, 'n': 1, 'A': 1, 'p': 1}
{'I': 1, 't': 2, ' ': 7, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 1, 'd': 2, 'y': 1, 'n': 1, 'A': 1, 'p': 1}
{'I': 1, 't': 2, ' ': 7, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 2, 'y': 1, 'n': 1, 'A': 1, 'p': 1}
{'I': 1, 't': 2, ' ': 7, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 2, 'y': 1, 'n': 1, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 2, ' ': 8, 'w': 1, 'a': 3, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 2, 'y': 1, 'n': 1, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 2, ' ': 8, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 2, 'y': 1, 'n': 1, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 2, ' ': 8, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 2, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 2, ' ': 8, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 2, ' ': 9, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 3, ' ': 9, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 1, 'c': 1, 'o': 1, 'l': 2, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 3, ' ': 9, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 1, 'o': 1, 'l': 2, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1}
{'I': 1, 't': 3, ' ': 9, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 1, 'o': 1, 'l': 2, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1}
{'I': 1, 't': 3, ' ': 10, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 1, 'o': 1, 'l': 2, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1}
{'I': 1, 't': 3, ' ': 10, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 2, 'o': 1, 'l': 2, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1}
{'I': 1, 't': 3, ' ': 10, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 2, 'o': 1, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1}
{'I': 1, 't': 3, ' ': 10, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 2, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1}
{'I': 1, 't': 3, ' ': 10, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1}
{'I': 1, 't': 3, ' ': 10, 'w': 1, 'a': 4, 's': 1, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1, 'k': 1}
{'I': 1, 't': 3, ' ': 10, 'w': 1, 'a': 4, 's': 2, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1, 'k': 1}
{'I': 1, 't': 3, ' ': 11, 'w': 1, 'a': 4, 's': 2, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1, 'k': 1}
{'I': 1, 't': 3, ' ': 11, 'w': 2, 'a': 4, 's': 2, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 1, 'k': 1}
{'I': 1, 't': 3, ' ': 11, 'w': 2, 'a': 4, 's': 2, 'b': 1, 'r': 2, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 2, 'k': 1}
{'I': 1, 't': 3, ' ': 11, 'w': 2, 'a': 4, 's': 2, 'b': 1, 'r': 3, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 2, 'k': 1}
{'I': 1, 't': 3, ' ': 11, 'w': 2, 'a': 4, 's': 2, 'b': 1, 'r': 3, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 1}
{'I': 1, 't': 3, ' ': 12, 'w': 2, 'a': 4, 's': 2, 'b': 1, 'r': 3, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 1}
{'I': 1, 't': 3, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 3, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 1}
{'I': 1, 't': 4, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 3, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 1}
{'I': 1, 't': 4, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 3, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 1}
{'I': 1, 't': 4, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 4, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 1}
{'I': 1, 't': 4, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 4, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 4, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 5, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 2, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 4, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 5, 'g': 1, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 4, ' ': 12, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 5, 'g': 2, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 4, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 5, 'g': 2, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 5, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 5, 'g': 2, 'h': 2, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 5, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 5, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 5, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 4, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 5, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 6, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 3, 'k': 2}
{'I': 1, 't': 6, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 4, 'k': 2}
{'I': 1, 't': 6, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 3, 'A': 1, 'p': 1, ',': 1, 'e': 5, 'k': 2}
{'I': 1, 't': 6, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 4, 'A': 1, 'p': 1, ',': 1, 'e': 5, 'k': 2}
{'I': 1, 't': 6, ' ': 13, 'w': 2, 'a': 4, 's': 3, 'b': 1, 'r': 5, 'i': 6, 'g': 2, 'h': 3, 'c': 3, 'o': 2, 'l': 3, 'd': 3, 'y': 1, 'n': 4, 'A': 1, 'p': 1, ',': 1, 'e': 5, 'k': 2, '.': 1}
这样看起来比较费劲,可以引入pprint模块,这样就可以美观输出结果了,显得更直观、更优雅。
输出的结果如下:
{' ': 13,
',': 1,
'.': 1,
'A': 1,
'I': 1,
'a': 4,
'b': 1,
'c': 3,
'd': 3,
'e': 5,
'g': 2,
'h': 3,
'i': 6,
'k': 2,
'l': 3,
'n': 4,
'o': 2,
'p': 1,
'r': 5,
's': 3,
't': 6,
'w': 2,
'y': 1}
>>>
小结一下:通过本章节的学习,掌握了关于字典方面的相关知识,字典是非常有用的,因为开发者可以把一些项(键)映射到另一些项(值),不像列表只包含一系列有序的值。字典中的值是通过方括号访问的,像列表一样。字典不使用整数索引,而是用各种数据类型如整型、浮点型或元组作为键,通过将程序中的值组织成数据结构,开发者可以创建真实世界事物的模型。字典和结构化数据的学习,让我认识到Python这类解释性语言显得更宽泛化,不像C或C++,不拘束于数据类型,不用考虑占用字节长度,提供了另一种编程思想。此次分享告一段落,与大家共勉。
- 2024-05-12
-
发表了主题帖:
《python编程快速上手》第4篇:python之列表应用
Python中的“列表”是一个值,包含由多个值构成的序列。“列表值”是指列表本身,而不是指列表值之内的那些值。列表中的值也称为“表项”。变量名后面方括号内的整数被称为“索引”。列表中第一个值的索引是0,第二个值的索引是1,第三个值的索引是2,依次类推。
由上可知,如果使用的索引超出了列表值的个数,Python将给出IndexError错误信息,索引只能是整数,不能是浮点数。第一个索引表明使用哪个列表值,第二个索引表明该列表值中的值。比如spam[0][1]即第一个列表中的第二值,如果只使用一个索引,程序将输出该索引的完整列表值。
虽然索引从0开始并向上增长,但也可以用负整数作为索引。整数值-1指的是列表中的最后一个索引,-2指的是列表中倒数第二个索引。索引可以从列表中取得单个值一样,“切片”可以从列表中取得多个值,结果是一个新列表。切片用一对方括号来表示它的起止,像索引一样,它有两个由冒号分隔的整数。在一个切片中,第一个整数是切片开始处的索引,第二个整数是切片结束处的索引。切片向上增长,直至第二个索引的值,注但不包括它。作为快捷方法,可以省略切片中冒号两边的一个索引或者两个索引。省略第一个索引相当于使用索引0或从列表的开始处开始。省略第二个索引相当于使用列表的长度,意味着切片直接至列表末尾。
使用len()函数取得列表的长度
使用索引改变列表中的值,方法如下图所示:
列表可以连接和复制,就像字符串一样,使用del语句可以实现从列表中删除某一个值。
此书还介绍了使用列表的基本方法,有用于循环中,in和not in操作符可以确定一个值是否在列表中。多重赋值技巧让你在一行代码中,用列表中的值为多个变量赋值。列表可以与enumerate()函数,random.choice()和random.shuffle()函数一起使用。使用index()方法在列表中查找值,用append()方法和insert()方法在列表中添加值。
使用remove()方法从列表中删除值,使用sort()方法将列表中的值排序,使用reverse()方法反转列表中的值。
此次学习到此结束,受益匪浅,觉得Python的确很灵活,很人性化。
- 2024-05-03
-
发表了主题帖:
《python编程快速上手》第3篇:python之控制流与函数处理
Python的控制流语句的开始部分通常是“条件”,接下来是一个代码块。条件只是在控制流语句的上下文中更具体的名称,条件总是求值为一个布尔值:True或False。代码块的判定遵循以下3条规则:①、缩进增加时,代码块开始。②、代码块可以包含其他代码块。③、缩进减少为零,或与外面包围代码块对齐,代码块就此结束。
控制流语句与C语言大体相同,如if语句、else语句、elif语句、以及while循环语句、break语句、continue语句,for循环中引入了range()函数,则可控制代码块执行的次数,如需提前结束程序,调用sys.exit()函数。
Python程序中可以调用一组基本的函数,这称为“内置函数”,包括print()、input()和len()函数。Python也包括一组模块,称为“标准库”。每个模块都是一个Python程序,包含一组相关的函数,可以嵌入到程序之中,采用import关键字可以导入相关模块,与C语言中的include类似。
书籍循序渐进,有控制流代码块引出函数知识,由def语句开始讲解,这相当于C语音中的宏定义#define,书籍对“定义”“调用”“传递”“参数”和“变元”等术语进行辨析。“调用栈”是Python记住每个函数调用后在哪里返回执行的方式。调用栈不是存储在程序的变量中,而是由python在后台处理它。当程序调用一个函数时,python在调用栈的顶部创建一个“帧对象”。帧对象保存了最初函数调用的行号,使得python可以记住返回的位置。如果进行了另一个函数调用,python会将另一个帧对象放在调用栈中,且在前一个帧对象之上。当函数调用返回时,python从栈顶部删除一个帧对象,并将执行转移至保存在其中的行号。值得注意的是,帧对象始终是从栈顶部添加和删除的,而不是从其他任意位置。
Python中函数存在局域和全局作用域,在被调用函数内赋值的变元和变量。处于该函数的“局部作用域”中。在所有函数之外赋值单变量,处于“全局作用域”中。处于局部作用域中的变量,被称为“局部变量”。处于全局作用域中的变量,被称为“全局变量”。一个变量必属于其中一种,不能既是局部的又是全局的。
一个函数被调用时,就创建一个局部作用域。在这个函数内赋值的所用变量,存在于该局部作用域内。该函数返回时,这个局部作用域就被销毁了,这些变量就丢失了。下次调用这个函数时,局部变量不会记得该函数上次被调用时它们保存的值。作用域非常重要,理由如下:
一、全局作用域中的代码不能使用任何局部变量。
二、局部作用域中的代码可以访问全局变量。
三、一个函数的局部作用域中的代码,不能使用其他局部作用域中的变量。
四、在不同的作用域中,你可以用相同的名字命名不同的变量。
综上所述,函数是将代码逻辑分组的主要方式,函数中的变量存在于它们自己的局部作用域内,一个函数中的代码不能直接影响其他函数中变量的值。这限制了哪些代码才能改变变量的值,对于调式代码是很有帮助的。函数是很好的工具,可帮助编程人员组织代码,它们以参数的形式接收输入,以返回值的形式产生输出。它们内部的代码不会影响其他函数中的变量。
- 2024-05-02
-
发表了主题帖:
《python编程快速上手》第2篇:python基础语法篇
Python编程语言有许多语法结构、标准库函数和交互式开发环境功能。由于之前并没有接触Python脚本程序,但通过对此书的前几章内容学习,感觉与C语言有点类似,但也有许多地方不同之处。
Python数学操作符的优先级与数学中类似。**操作符表指数,*、/、//和%操作符,从左到右;+、- 操作符最后求值,同样的可以使用括号来改变通常的优先级。Python中的数据类型也有整型、浮点型、字符串类型连接和复制小结中,当在操作两个整型或浮点型值时,+是相加操作符,但在两个字符串之间,它则表式将字符串连接起来,成为“字符串连接”操作符。
Python语法中,“变量”就像计算机内存中的一个盒子,其中可以存放一个值。变量名命名也是有规则的,①、只能是一个词,不带空格。②、只能包含字母、数字和下划线“_”字符。③、不能以数字开头。变量名有区分大小写的。
接着引出了print()、input()、len()、str()、int()以及float()函数,可谓是受益匪浅,print()和input()函数处理简单的文本输出到屏幕和键盘输入;len()函数接收一个字符串,并求值为该字符串中字符的数目。str()、int()和float()函数将传入它们的值求值为字符串、整数或浮点数形式。
每个知识点,文中都有相关的程序举例,并且附带详细的程序剖析,可以让小白无门槛学习Python语法知识。书籍中还附带一本《Python学习效率手册》笔记本,8个星期的随学随记,“一个人走得慢,一群人学得稳”,经过基本语法的学习,觉得Python语言的编写格式有严格的讲究,包括首字符的缩进,没有C语言那么随意。
-
发表了主题帖:
《python编程快速上手》第1篇:开启扉页
本书的全名《Python编程快速上手---让繁琐工作自动化 第2版》,收到有段时间了,次书籍在异步社区有提供出售。书籍采用薄膜包装,防尘防水。书籍的正面、底面纸质华丽。
拆开新鲜薄膜,打开书籍的扉页,此书由中国工信出版集团,人民邮电出版社,字数618千字,2023年7月河北第15次印刷,本书分为两部分,第一部分介绍了基本的Python编程概念,第二部分介绍了一些不同的任务。前言部分作者申明了此书中的程序运行在Python3上,有一部分程序如果在Python2上也行不能正常运行。笔者早在之前就已经安装好python了,在计算机终端中输入:python -v,可知版本为3.11。
下载基于windows x64版本Mu编辑器软件,并傻瓜式安装,默认是安装到C盘个人本地路径下,并以python编程风格启动Mu。
此书集各大编程爱好者之精华,用户可通过扫码添加异步助手,获取本书籍的配套资源,如广大读者有发现错误,可到异步社区搜索此书名,进入本书页面,“提交勘误”,审核通过后可获得相应的奖励。前言篇到此结束,后续精彩继续。
- 2024-04-12
-
回复了主题帖:
读书入围名单:《Python编程快速上手 让繁琐工作自动化 第2版》
个人信息无误,确认可以完成阅读分享计划。
- 2024-03-28
-
回复了主题帖:
《原子Linux驱动开发》下载mp135开发板的SDK
这不是发阅读心得吗?怎么在拉取SDK包,调试代码了啊
- 2024-03-02
-
发表了主题帖:
基于MSPM0L1306 LaunchPad的板卡温度传感器实测
本帖最后由 yin_wu_qing 于 2024-3-2 23:39 编辑
根据宣传海报可知,LP-MSPM0L1306 LaunchPad开发套件是基于MSPM0L1306的易用型评估模块, 包含在MSPM0L1306 M0+ MCU 平台上开始开发所需要的全部资源,包括用于编程、调试和能量测量的板载调试探针。 该板包含三个按钮、两个LED(其中一个是RGB LED)、模拟温度传感器和光传感器。此次就板载的“TMP6131DECT”温度传感器进行检测。
通过上方的电路原理图可知,如果需要对温度传感器进出检测,则需要将J15通过跳线帽短接,形成电阻上拉部分电路。于此同时,还需要将J1的1、2脚短接在一起,这样才能将温度传感器连接到电路中。如果短接2、3脚,则是连接到光敏传感器。
关于这款温度传感器,TI官方提供的数据手册如下:
如何使用该温度传感器,需要借助ADC转换接口,TI专门提供了设计工具,使用该工具可设计多款传感器的基本配置代码。
这里使用“Thermistor Design Tool - Voltage Bias”文档来设置,如下图所示,设置好对应的参数,该工具可得出转换接口函数。
通过CCS从SDK中导出“adc_to_uart_LP_MSPM0L1306_nortos_ticlang”工程,然后双击工程中的“adc_to_uart.syscfg”文件,则可调出sysconfig GUI界面,将ADC的GPIO管脚设置成PA15。
部分的参考代码如下:
编译后自动生成的“ti_msp_dl_config.c”源码如下:
#include "ti_msp_dl_config.h"
/*
* ======== SYSCFG_DL_init ========
* Perform any initialization needed before using any board APIs
*/
SYSCONFIG_WEAK void SYSCFG_DL_init(void)
{
SYSCFG_DL_initPower();
SYSCFG_DL_GPIO_init();
/* Module-Specific Initializations*/
SYSCFG_DL_SYSCTL_init();
SYSCFG_DL_UART_0_init();
SYSCFG_DL_ADC12_0_init();
}
SYSCONFIG_WEAK void SYSCFG_DL_initPower(void)
{
DL_GPIO_reset(GPIOA);
DL_UART_Main_reset(UART_0_INST);
DL_ADC12_reset(ADC12_0_INST);
DL_GPIO_enablePower(GPIOA);
DL_UART_Main_enablePower(UART_0_INST);
DL_ADC12_enablePower(ADC12_0_INST);
delay_cycles(POWER_STARTUP_DELAY);
}
SYSCONFIG_WEAK void SYSCFG_DL_GPIO_init(void)
{
DL_GPIO_initPeripheralOutputFunction(GPIO_UART_0_IOMUX_TX, GPIO_UART_0_IOMUX_TX_FUNC);
}
SYSCONFIG_WEAK void SYSCFG_DL_SYSCTL_init(void)
{
//Low Power Mode is configured to be SLEEP0
DL_SYSCTL_setBORThreshold(DL_SYSCTL_BOR_THRESHOLD_LEVEL_0);
DL_SYSCTL_setSYSOSCFreq(DL_SYSCTL_SYSOSC_FREQ_BASE);
DL_SYSCTL_setMCLKDivider(DL_SYSCTL_MCLK_DIVIDER_DISABLE);
}
static const DL_UART_Main_ClockConfig gUART_0ClockConfig = {
.clockSel = DL_UART_MAIN_CLOCK_BUSCLK,
.divideRatio = DL_UART_MAIN_CLOCK_DIVIDE_RATIO_1
};
static const DL_UART_Main_Config gUART_0Config = {
.mode = DL_UART_MAIN_MODE_NORMAL,
.direction = DL_UART_MAIN_DIRECTION_TX,
.flowControl = DL_UART_MAIN_FLOW_CONTROL_NONE,
.parity = DL_UART_MAIN_PARITY_NONE,
.wordLength = DL_UART_MAIN_WORD_LENGTH_8_BITS,
.stopBits = DL_UART_MAIN_STOP_BITS_ONE
};
SYSCONFIG_WEAK void SYSCFG_DL_UART_0_init(void)
{
DL_UART_Main_setClockConfig(UART_0_INST, (DL_UART_Main_ClockConfig *) &gUART_0ClockConfig);
DL_UART_Main_init(UART_0_INST, (DL_UART_Main_Config *) &gUART_0Config);
/*
* Configure baud rate by setting oversampling and baud rate divisors.
* Target baud rate: 115200
* Actual baud rate: 115211.52
*/
DL_UART_Main_setOversampling(UART_0_INST, DL_UART_OVERSAMPLING_RATE_16X);
DL_UART_Main_setBaudRateDivisor(UART_0_INST,UART_0_IBRD_32_MHZ_115200_BAUD,
UART_0_FBRD_32_MHZ_115200_BAUD);
/* Configure FIFOs */
DL_UART_Main_enableFIFOs(UART_0_INST);
DL_UART_Main_setTXFIFOThreshold(UART_0_INST, DL_UART_TX_FIFO_LEVEL_1_2_EMPTY);
DL_UART_Main_enable(UART_0_INST);
}
/* ADC12_0 Initialization */
static const DL_ADC12_ClockConfig gADC12_0ClockConfig = {
.clockSel = DL_ADC12_CLOCK_ULPCLK,
.divideRatio = DL_ADC12_CLOCK_DIVIDE_8,
.freqRange = DL_ADC12_CLOCK_FREQ_RANGE_24_TO_32,
};
SYSCONFIG_WEAK void SYSCFG_DL_ADC12_0_init(void)
{
DL_ADC12_setClockConfig(ADC12_0_INST, (DL_ADC12_ClockConfig *) &gADC12_0ClockConfig);
DL_ADC12_configConversionMem(ADC12_0_INST, ADC12_0_ADCMEM_0,
DL_ADC12_INPUT_CHAN_9, DL_ADC12_REFERENCE_VOLTAGE_VDDA, DL_ADC12_SAMPLE_TIMER_SOURCE_SCOMP0, DL_ADC12_AVERAGING_MODE_DISABLED,
DL_ADC12_BURN_OUT_SOURCE_DISABLED, DL_ADC12_TRIGGER_MODE_AUTO_NEXT, DL_ADC12_WINDOWS_COMP_MODE_DISABLED);
DL_ADC12_setSampleTime0(ADC12_0_INST,500);
/* Enable ADC12 interrupt */
DL_ADC12_clearInterruptStatus(ADC12_0_INST,(DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED));
DL_ADC12_enableInterrupt(ADC12_0_INST,(DL_ADC12_INTERRUPT_MEM0_RESULT_LOADED));
DL_ADC12_enableConversions(ADC12_0_INST);
}
“adc_to_uart.c”代码实现如下,这里将uart发送接口函数改成printf打印,这样可以在CCS中的Console窗口实时打印输出温度传感器采样的温度值。
#include "ti_msp_dl_config.h"
#include <stdio.h>
#include <math.h>
volatile bool gCheckADC;
volatile uint16_t gADCResult;
volatile float temperature;
float VBias = 3.30;
unsigned int ADC_BITS = 4096;
float VTEMP = 0;
float THRM_TEMP = 0;
float Thermistor(int raw_ADC)
{
// THRM calculations - 4th order polynomial regression
VTEMP = 0;
int THRM_ADC = raw_ADC;
float THRM_A0 = -4.232811E+02 ;
float THRM_A1 = 4.728797E+02 ;
float THRM_A2 = -1.988841E+02 ;
float THRM_A3 = 4.869521E+01 ;
float THRM_A4 = -1.158754E+00 ;
VTEMP = (VBias/ADC_BITS) * THRM_ADC;
THRM_TEMP =(THRM_A4 * powf( VTEMP,4)) + (THRM_A3 * powf( VTEMP,3)) + (THRM_A2 * powf( VTEMP,2)) + (THRM_A1 * VTEMP) + THRM_A0;
return THRM_TEMP;
}
int main(void)
{
SYSCFG_DL_init();
NVIC_EnableIRQ(ADC12_0_INST_INT_IRQN);
gCheckADC = false;
while (1) {
DL_ADC12_startConversion(ADC12_0_INST);
while (false == gCheckADC) {
__WFE();
}
/*
* UART is 8 bits and the ADC result is 16 bits
* Split the ADC result into 2 then send via UART.
*/
gADCResult = DL_ADC12_getMemResult(ADC12_0_INST, DL_ADC12_MEM_IDX_0);
// uint8_t lowbyte = (uint8_t)(gADCResult & 0xFF);
// uint8_t highbyte = (uint8_t)((gADCResult >> 8) & 0xFF);
temperature = Thermistor(gADCResult);
printf("ADC=%d, temperature=%.2f\n", gADCResult, temperature);
// DL_UART_Main_transmitData(UART_0_INST, highbyte);
// DL_UART_Main_transmitData(UART_0_INST, lowbyte);
gCheckADC = false;
DL_ADC12_enableConversions(ADC12_0_INST);
}
}
void ADC12_0_INST_IRQHandler(void)
{
switch (DL_ADC12_getPendingInterrupt(ADC12_0_INST)) {
case DL_ADC12_IIDX_MEM0_RESULT_LOADED:
gCheckADC = true;
break;
default:
break;
}
}
开发板的硬件连接如下图所示,其中需注意J1处的跳线帽设置。
将编译后的程序下载到开发板后,即可观察到温度传感器实时采样的温度值,此时此刻南方的温度感觉有点冷。如果将手指靠近TMP6131,温度值会立马上升,足见其灵敏度比较高。此次分享内容告一段落,感谢来访阅读,欢迎留言交流。
- 2024-02-26
-
发表了主题帖:
基于MSPM0L1306 LaunchPad的四相五线式步进电机驱动
承接上期的“点灯控制”帖子,这期使用MSPM0L1306 LaunchPad开发板对常见的四相五线式步进电机进行驱动。电机型号:28BYJ48,本次实验是基于“pwm_led_driver_LP_MSPM0L1306_nortos_ticlang”例程展开的,该工程实现LED2指示灯的呼吸效果。
首先打开“Code Composer Studio”工具,导入SDK,勾选需要加载的参考例程,这里选择采用TI官方编译器的“pwm_led_driver_LP_MSPM0L1306_nortos_ticlang”例程。
在工程的根目录下,手动创建“bsp_uln2003.c”与“bsp_uln2003.h”源文件,双击打开“pwm_led_driver.syscfg”文件,调出sysconfig图形设置界面。
根据功能需求,使用到4个GPIO口,实现对四相的控制。
添加4个有效的GPIO口,如下图所示。
编译后,在“Generated Source”目录下自动更新“ti_msp_dl_config.c”与“ti_msp_dl_config.h”源文件。
根据“ti_msp_dl_config.h”源文件,可清晰得知道系统自动分配的有效GPIO口。
由上述系统分配,在“bsp_uln2003.h”源文件中完善管脚的定义。
在工程Properties属性中,包含“bsp_uln2003.h”头文件所在的路径。
接着编写初始化GPIO口及驱动代码,部分代码展示如下:
#include "bsp_uln2003.h"
#include "ti_msp_dl_config.h"
void ULN2003_GPIO_Init(void)
{
DL_GPIO_enableOutput(GPIOA,ULN2003_GPIO_PIN_A);
DL_GPIO_enableOutput(GPIOA,ULN2003_GPIO_PIN_B);
DL_GPIO_enableOutput(GPIOA,ULN2003_GPIO_PIN_C);
DL_GPIO_enableOutput(GPIOA,ULN2003_GPIO_PIN_D);
DL_GPIO_clearPins(GPIOA,ULN2003_GPIO_PIN_A);
DL_GPIO_clearPins(GPIOA,ULN2003_GPIO_PIN_B);
DL_GPIO_clearPins(GPIOA,ULN2003_GPIO_PIN_C);
DL_GPIO_clearPins(GPIOA,ULN2003_GPIO_PIN_D);
}
#include "ti_msp_dl_config.h"
#include "oled.h"
#include "bsp_uln2003.h"
int pwm_count = 1800; // initial ccr count based on 10% duty cycle
int dc = 10; // initialized to 10 % duty cycle
int mode = 1; // 1 = up (will indicate you need to increase dc), 0 = down (will
// decrease dc)
#define STEPMOTOR_DIRECTION 0 // 1:顺时针 0:逆时针
#define STEPMOTOR_SPEED 10 // 速度,该值越小,速度越快,最小不能小于10
// 速度,该值越小,速度越快,最小不能小于10
uint8_t speed=STEPMOTOR_SPEED;
// 转动圈数:28BYJ-48步进电机的步距角度为5.625/64,即每64个脉冲转5.625度
// 要转一圈需要360/5.625*64=4096个脉冲。
// 8个节拍控制:A->AB->B->BC->C->CD->D->DA
uint16_t step_motor[8]={0xFC7F,0xFCFF,0xFCBF,0xFDBF,0xFD3F,0xFF3F,0xFE3F,0xFE7F};
/**
* 函数功能: 输出一个数据给ULN2003从而实现向步进电机发送一个脉冲
* 输入参数: step:序列号,选择step_motor数组对应的数据
* direction:方向选择
* 可选值:0:顺时针
* 1:逆时针
* 返 回 值: 无
*/
static void step_motor_pulse(uint8_t step,uint8_t direction)
{
uint8_t temp=step;
if(direction==0)
{
temp=8-step;
}
switch(temp)
{
case 0:
A_ON();B_OFF();C_OFF();D_OFF();
break;
case 1:
A_ON();B_ON();C_OFF();D_OFF();
break;
case 2:
A_OFF();B_ON();C_OFF();D_OFF();
break;
case 3:
A_OFF();B_ON();C_ON();D_OFF();
break;
case 4:
A_OFF();B_OFF();C_ON();D_OFF();
break;
case 5:
A_OFF();B_OFF();C_ON();D_ON();
break;
case 6:
A_OFF();B_OFF();C_OFF();D_ON();
break;
case 7:
A_ON();B_OFF();C_OFF();D_ON();
break;
default:
break;
}
}
void motor_run(void)
{
static uint8_t count=0,step=0;
static uint16_t pulse_count=0;
for(int time=4500; time>0; time--)
{
count++;
if(count==speed)
{
step_motor_pulse(step,STEPMOTOR_DIRECTION);
step++;
pulse_count++;
if(step==8) step=0;
count=0;
}
if(pulse_count==4096)
{
pulse_count=0;
}
delay_cycles(28000);
}
}
int main(void) {
SYSCFG_DL_init();
ULN2003_GPIO_Init();
NVIC_EnableIRQ(PWM_0_INST_INT_IRQN);
DL_TimerG_startCounter(PWM_0_INST);
while (1) {
motor_run();
__WFI();
}
}
void PWM_0_INST_IRQHandler(void) {
switch (DL_TimerG_getPendingInterrupt(PWM_0_INST)) {
case DL_TIMER_IIDX_LOAD:
if (dc <= 10) {
mode = 1;
} // if reached lowest dc (10%), increase dc
else if (dc >= 90) {
mode = 0;
} // if reached highest dc (90%), decrease dc
if (mode) {
pwm_count -= 10;
dc += 1;
} // up
if (!mode) {
pwm_count += 10;
dc -= 1;
} // down
DL_TimerG_setCaptureCompareValue(PWM_0_INST, pwm_count,DL_TIMER_CC_1_INDEX);
break;
default:
break;
}
}
编译后,直接debug即可将程序下载到开发板中,硬件连线如下:
基本实现了步进电机的驱动,逆时针旋转的演示效果如下所示,此次分享告一段落,谢谢EEWorld提供的评测机会,精彩再续。
[localvideo]0670379b944961843b2144479e0e8b39[/localvideo]
- 2024-02-20
-
发表了主题帖:
基于MSPM0L1306 LaunchPad的点灯控制
MSPM0L1306 LaunchPad开发套件主控为MSPM0L1306器件,提供高达64KB的嵌入式闪存程序存储器和高达4KB的SRAM。它们包含精度为±1%的高速片上振荡器,无需外部晶体。其他特性包括3通道DMA、16位和32位CRC加速器,以及各种高性能模拟外设。如何入手MSPM0L1306 LaunchPad开发套件呢?官方提供了参考短视频。
按照官方推荐的说明文档,①、首先需要准备好TI的官方IDE,即CCS。②、其次下载安装好基于MSPM0L1306的SDK。③、然后需要下载安装好图形化代码生成工具SysConfig。
登录TI官方论坛网站,下载好软件安装包,安装CCS编译工具,具体步骤如下:
下载好基于windows平台下的“mspm0_sdk_1_30_00_03”软件包,并安装好。
下载好“sysconfig-1.19.0_3426-setup”,安装MSPM0的图形化代码生成工具SysConfig。
以上3个必备软件都安装好了,等于基本环境已经构建好,接着需要将SDK与SysConfig导入到CCS工具中。
导入SDK中基于TI官方交叉编译器的点灯例程,点击编译。编译通过,然后使用Micro USB数据线与电脑相连接,如是首次连接,电脑的右下角会弹出提示安装XDS110驱动的对话框。
安装完成后,设备管理器中会自动出现两个串口端口。
此时直接点击CCS中的Debug按钮图标,会弹出XDS110 USB Debug需要升级的提示。
选择update后,进入到自动升级状态,升级完成后再给开发板重新上电。
在CCS中执行debug步骤,开发板进入调试阶段。点击全速运行,则会发现板上的LED1红色指示灯会一定频率闪烁。
void main_blinky(void)
{
/* Create the queue. */
xQueue = xQueueCreate(mainQUEUE_LENGTH, sizeof(uint32_t));
if (xQueue != NULL) {
/*
* Start the two tasks as described in the comments at the top of this
* file.
*/
xTaskCreate(
prvQueueReceiveTask, /* The function that implements the task. */
"Rx", /* The text name assigned to the task - for debug only as it is not used by the kernel. */
configMINIMAL_STACK_SIZE, /* The size of the stack to allocate to the task. */
(void *)
mainQUEUE_RECEIVE_PARAMETER, /* The parameter passed to the task - just to check the functionality. */
mainQUEUE_RECEIVE_TASK_PRIORITY, /* The priority assigned to the task. */
NULL); /* The task handle is not required, so NULL is passed. */
xTaskCreate(prvQueueSendTask, "TX", configMINIMAL_STACK_SIZE,
(void *) mainQUEUE_SEND_PARAMETER, mainQUEUE_SEND_TASK_PRIORITY,
NULL);
/* Start the tasks. */
vTaskStartScheduler();
}
/*
* If all is well, the scheduler will now be running, and the following
* line will never be reached. If the following line does execute, then
* there was insufficient FreeRTOS heap memory available for the idle
* and/or timer tasks to be created. See the memory management section on
* the FreeRTOS web site for more details.
*/
for (;;)
;
}
/*-----------------------------------------------------------*/
static void prvQueueSendTask(void *pvParameters)
{
TickType_t xNextWakeTime;
const unsigned long ulValueToSend = 100UL;
/* Check the task parameter is as expected. */
configASSERT(((unsigned long) pvParameters) == mainQUEUE_SEND_PARAMETER);
/* Initialize xNextWakeTime - this only needs to be done once. */
xNextWakeTime = xTaskGetTickCount();
for (;;) {
/*
* Place this task in the blocked state until it is time to run again.
* The block time is specified in ticks, the constant used converts
* ticks to ms. While in the Blocked state this task will not consume
* any CPU time.
*/
vTaskDelayUntil(&xNextWakeTime, mainQUEUE_SEND_FREQUENCY_MS);
/*
* Send to the queue - causing the queue receive task to unblock and
* toggle the LED. 0 is used as the block time so the sending operation
* will not block - it shouldn't need to block as the queue should always
* be empty at this point in the code.
*/
xQueueSend(xQueue, &ulValueToSend, 0U);
}
}
/*-----------------------------------------------------------*/
static void prvQueueReceiveTask(void *pvParameters)
{
unsigned long ulReceivedValue;
static const TickType_t xShortBlock = pdMS_TO_TICKS(50);
/* Check the task parameter is as expected. */
configASSERT(
((unsigned long) pvParameters) == mainQUEUE_RECEIVE_PARAMETER);
for (;;) {
/*
* Wait until something arrives in the queue - this task will block
* indefinitely provided INCLUDE_vTaskSuspend is set to 1 in
* FreeRTOSConfig.h.
*/
xQueueReceive(xQueue, &ulReceivedValue, portMAX_DELAY);
/*
* To get here something must have been received from the queue, but
* is it the expected value? If it is, toggle the LED.
*/
if (ulReceivedValue == 100UL) {
/*
* Blip the LED for a short while so as not to use too much
* power.
*/
DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
vTaskDelay(xShortBlock);
DL_GPIO_togglePins(GPIO_LEDS_PORT, GPIO_LEDS_USER_LED_1_PIN);
ulReceivedValue = 0U;
}
}
}
允许Debug后,编译完成后的程序通过XDS110调试器下载到开发板中,此时板上的LED显示状态如下图所示,LED1红灯闪烁。
硬件连接只需一个Micro USB即可实现板子的在线调试。
此次分享到处结束,参考MSPM0L1306入门指南手册可以快速搭建开发环境,熟悉官方主推的CCS集成开发工具,后续再细究MSPM0L1306外设驱动性能。
- 2024-02-19
-
发表了主题帖:
基于MSPM0L1306 LaunchPad的开箱评测
年前收到了MSPM0L1306 LaunchPad开发套件,MSPM0L1306是一款32位Arm®Cortex®-M0+ CPU,频率高达32MHz,该板卡上集成三个按钮、两个LED(其中一个是RGB LED)、模拟温度传感器和光传感器。收到的板卡是采用TI经典颜色的小纸盒包装。
主核心板采用防静电袋封装,附带一根MicroUSB的数据线,纸盒中还有几张关于板卡的管脚分布图及操作说明书,内容言简意赅,步骤有序。可以根据说明书快速获取到有关该板卡的开发资源。
再来看看核心主板,主板具有外部编程选项的板载XDS110调试探针,可用于超低功耗调试的EnergyTrace技术,支持使用GPIO和XDS110调用BSL。
官方推荐使用“TI Code Composer Studio IDE 或 IAR Embedded Workbench IDE”,板上采用多处跳线帽连接各功能接口,靠近Micro USB接口的MSP432是XDS110调试器主控MCU,开发板上的位置概览图如下:
板子的整体方框图如下:
开发板的底面虽然没有集成电子元器件,由于有焊接点,因此为了避免短路,板上的四个角边有预留定位孔,收到板卡时有提供两个定位胶塞卡扣,与两排的母座排插端子齐平,可作为支柱。板上的丝印显示网址:www.ti.com/launchpad
此次分享到此告一段落,关于板卡的SDK的详细资料,可跳转至:MSPM0 SDK 文档。部分参考资料如下: