搜档网
当前位置:搜档网 › 最新stm32学习之串口usart复习进程

最新stm32学习之串口usart复习进程

最新stm32学习之串口usart复习进程
最新stm32学习之串口usart复习进程

STM32学习之串口USART

STM32 的串口是相当丰富的。最多可提供5路串口,有分数波特率发生器、支持单线光通信和半双工单线通讯、支持LIN、智能卡协议和IrDA SIR ENDEC 规范(仅串口3 支持)、具有DMA 等。串口最基本的设置,就是波特率的设置。STM32 的串口使用起来还是蛮简单的,只要你开启了串口时钟,并设置相应IO口的模式,然后配置一下波特率,数据位长度,奇偶校验位等信息,就可以使用了。

1、串口时钟使能。串口作为STM32 的一个外设,其时钟由外设始终使能寄存器控制,这里我们使用的串口1是在APB2ENR 寄存器的第14 位。除了串口1 的时钟使能在APB2ENR寄存器,其他串口的时钟使能位都在APB1ENR。

1、串口的作用:用在STM32板子和PC机通信的。我们调试的时候,无法知道是否正确,就可以用STM32的cpu,给串口输出一些信息给PC,我们通过屏幕(实际上是终端串口软件),可以看到这些信息,从而知道当前程序的错误可能出现的位置。当然,也可以在PC的键盘敲打命令,让串口帮传递给STM32板子,来执行这些命令。

2、串口的工作模式一般有两种方式:查询和中断

(1)查询:串口程序不断地循环查询,看看当前有没有数据要它传,如果有,就帮助传送(可以从PC到STM32板子,也可以从STM32 板子到PC)。

(2)中断:平时串口只要打开中断即可。如果发现有一个中断来,则意味着要它帮助传输数据——它就马上进行数据的传送。同样,可以从PC到STM32板子,也可以从STM32板子到PC 。

步骤一从硬件开始学习。大家先打开芯达STM32开发板附带的原理图。找到串口部分。笔者把它截图如下。我们发现,串口模块的电路是这样的:STM32的CPU引脚,通过两个PA端口的引脚PA10和PA9(此两个引脚复用USART),连接到一个SP3232芯片,或者MAX232芯片。然后再连接到DB9串口座上。由于232芯片可以允许走两路信号,因此,我们扩展了一个串口COM2,请注意,如无特别说明,我们都将使用COM1。

SP3232EEN芯片能帮助把数据信号转换成电脑232接口能识别的信号。其转换是自动进行的。因此,我们只需要把要发送的数据送给引脚PA9,然后再串口座的引脚3上去接收数据即可。反之,接收数据也是一样。

步骤二初始化串口。

打开《STM32F103xxx参考手册》与《STM32固件库使用手册》。我们的思路和之前一样,根据固件库使用手册中给出的步骤来配置串口。

1、要声明一个结构:

GPIO_InitTypeDef GPIO_InitStructure;

USART_InitTypeDefUSART_InitStructure;

这里顺便也声明了GPIO的结构。原因是:串口是需要使用IO口来进行发送和接收的。

2、设置该结构中的成员:

串口的结构成员设置如下:

USART_StructInit(&USART_InitStructure);

USART_https://www.sodocs.net/doc/0718475687.html,ART_BaudRate=115200;

USART_https://www.sodocs.net/doc/0718475687.html,ART_WordLength=USART_WordLength_8b; USART_https://www.sodocs.net/doc/0718475687.html,ART_StopBits=USART_StopBits_1; USART_https://www.sodocs.net/doc/0718475687.html,ART_Parity=USART_Parity_No;

USART_https://www.sodocs.net/doc/0718475687.html,ART_Mode=USART_Mode_Rx|USART_Mod e_Tx;

USART_https://www.sodocs.net/doc/0718475687.html,ART_HardwareFlowControl

=USART_HardwareFlowControl_None;

GPIO结构的成员设置如下:

GPIO_StructInit(&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_9;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_AF_PP;

GPIO_Init(GPIOA,&GPIO_InitStructure);

GPIO_InitStructure.GPIO_Pin=GPIO_Pin_10;

GPIO_InitStructure.GPIO_Mode=GPIO_Mode_IN_FLOATING; GPIO_Init(GPIOA,&GPIO_InitStructure);

3、调用函数x xx_Init()来初始化外设(包括IO和USART):USART的初始化函:USART_Init(USART1,&USART_InitStructure); 由于GPIO的外设初始化已经放在成员设置后面,因此这里没有列出来。

4、调用xxx_Cmd(xxx,ENABLE);函数来使能外设。

这里只需要使能USART即可。GPIO的固件中,没有使能即可使用。USART_Cmd(USART1,ENABLE);由于本文档使用的是中断方式来触发串口收发数据,因此,我们在使能串口之前,也把发送和接收的中断使能打开:

USART_ITConfig(USART1,USART_IT_RXNE,ENABLE);

USART_ITConfig(USART1,USART_IT_TXE,ENABLE);

5、别忘了加上外设的时钟使能哈~

GPIOA和USART都在APB2上。因此我们调用的函数如下:RCC_APB2PeriphClockCmd(RCC_APB2Periph_USART1|RCC_APB2 Periph_GPIOA|RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOC|R CC_APB2Periph_GPIOD|RCC_APB2Periph_GPIOE,ENABLE);

步骤三操作串口收发数据

芯达STM32的思路是:首先让STM32的CPU发送一些欢迎信息,从串口打印出来。然后接收中断,该中断来自键盘输入。只要键盘输入一个字符,即打印出该字符,从而验证串口编程是否成功。

固件库的函数如何让串口发送和接收数据呢?它给我们提供了两个函数:

USART_SendData(); ——省略函数参数

USART_ReceiveData();

先来看发送。我们的程序在初始化串口之后,马上就会打印欢迎信息。也就是从STM32的CPU发送信息,在电脑屏幕上显示出来,只要如下操作即可:

/*============USART打印欢迎信息==============*/

for(i=0;TxBuf1[i]!='\0';i++){

USART_SendData(USART1,TxBuf1[i]);

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); }

TxBuf1是一个发送缓存。我们事先把数据放在这个数组里了:unsignedcharTxBuf1[100]="这里可以自定义需要输出到串口的字符"; 这里要注意的是,当我们发送一个字符后,必须查看状态标志,这里是发送是否完成的标志:USART_FLAG_TC,如果发送完成了,则才可以发送下一个数据。函数USART_GetFlagStatus();就是用来做这个判断的。

下面开始另外一个操作:键盘输入什么字符,就得显示什么字符。我们的代码如下:

while(1)

{

GPIO_SetBits(GPIOE,GPIO_Pin_1);

RX_status=USART_GetFlagStatus(USART1,USART_FLAG_RXNE);

if(RX_status==SET)

{

USART_SendData(USART1,USART_ReceiveData(USART1));

while(USART_GetFlagStatus(USART1,USART_FLAG_TC)==RESET); GPIO_ResetBits(GPIOE,GPIO_Pin_1);

Delay(0xFFFFF);

}

}

先判断接收的状态标志USART_FLAG_RXNE,如果接收的寄存器非空,说明已经接收到键盘发送来的数据,于是就把这个数据从接收缓存中取出来,发送给电脑。这样电脑就可以看到刚才敲入的字符了。USART_ReceiveData(USART1);这个函数是从接收缓存取出数据。我们在这个while中,还加入了GPIO的函数:

GPIO_SetBits(GPIOC,GPIO_Pin_0);

GPIO_ResetBits(GPIOC,GPIO_Pin_0);

这两个函数,SetBits,表示对GPIOC端口的第0个引脚置1。ResetBits,清零。由于芯达STM32开发板上,GPIOC端口上的第0引脚连着一个LED灯,所以,我们可以通过观察LED灯是否闪烁来判断串口是否正在发送。常用世界各大城市三字代码

STM32学习笔记

输入模式初始化GPIOE2,3,4 ①IO口初始化:GPIO_InitTypeDef GPIO_InitStructure; ②使能PORTA,PORTE时钟: RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOA|RCC_APB2Periph_GPIOE,ENABLE); ③PE.2.3.4端口配置:GPIO_InitStructure.GPIO_Pin = GPIO_Pin_2|GPIO_Pin_3|GPIO_Pin_4; ④设置成(上拉)输入:GPIO_InitStructure.GPIO_Mode = GPIO_Mode_IPU; ⑤GPIO_Init(GPIOE, &GPIO_InitStructure); 输出模式初始化 ①IO口初始化:GPIO_InitTypeDef GPIO_InitStructure; ②使能PB,PE端口时钟 RCC_APB2PeriphClockCmd(RCC_APB2Periph_GPIOB|RCC_APB2Periph_GPIOE, ENABLE); ③3LED0-->PB.5 端口配置GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; ④设置(推挽)输出模式GPIO_InitStructure.GPIO_Mode = GPIO_Mode_Out_PP; ⑤设置IO口速度为50MHz GPIO_InitStructure.GPIO_Speed = GPIO_Speed_50MHz; ⑥说明初始化哪个端口GPIO_Init(GPIOB, &GPIO_InitStructure); 在LED灯试验中初始为高电平灭GPIO_SetBits(GPIOB,GPIO_Pin_5); 再初始化相同发输出模式时③④⑤可省略例如(经实验初始化恰好为不同IO口相同IO序号③可省略,应该不规范吧) GPIO_InitStructure.GPIO_Pin = GPIO_Pin_5; //LED1-->PE.5 端口配置, 推挽输出GPIO_Init(GPIOE, &GPIO_InitStructure); //推挽输出,IO口速度为50MHz GPIO_SetBits(GPIOE,GPIO_Pin_5); //PE.5 输出高 1,头文件可以定义所用的函数列表,方便查阅你可以调用的函数; 2,头文件可以定义很多宏定义,就是一些全局静态变量的定义,在这样的情况下,只要修改头文件的内容,程序就可以做相应的修改,不用亲自跑到繁琐的代码内去搜索。 3,头文件只是声明,不占内存空间,要知道其执行过程,要看你头文件所申明的函数是在哪个.c文件里定义的,才知道。 4,他并不是C自带的,可以不用。 5,调用了头文件,就等于赋予了调用某些函数的权限,如果你要算一个数的N次方,就要调用Pow()函数,而这个函数是定义在math.c里面的,要用这个函数,就必需调用math.h 这个头文件。

运筹学课程设计指导书

运筹学课程设计指导书 一、课程设计目的 1、初步掌握运筹学知识在管理问题中应用的基本方法与步骤; 2、巩固和加深对所学运筹学理论知识及方法的理解与掌握; 3、锻炼从管理实践中发掘、提炼问题,分析问题,选择建立运筹学模型,利用模型求解问题,并对问题的解进行分析与评价的综合应用能力; 4、通过利用运筹学计算机软件求解模型的操作,掌握运筹学计算软件的基本操作方法,并了解计算机在运筹学中的应用; 二、课程设计内容与步骤 第一部分是基本实验,为必做部分;需要每位同学单独完成,并写出相应的实验报告。第二部分是提高部分,题目自选或自拟,锻炼综合应用运筹学知识及软件解决实际问题的能力;可以单独完成,也可以合作完成(最多3人一组),写出相应的报告。 1、基本实验在完成基本实验后,每位同学要按照实验要求完成实验报告,实验报告应包括问题描述、建模、上机求解、结果分析及答辩几方面。实验报告必须是打印稿(word文档等),手写稿无效。请大家按照要求认真完成实验报告,如果两份实验报告雷同,或相差很少,则两份实验报告均为0分,其它抄袭情况,将根据抄袭多少扣分。(约占总分的70%) 2、提高部分根据自己的兴趣或所查找的资料,从实际情况出发,自拟题目;在实验报告中,陈述问题,建立模型,求解,结果分析,此部分应着重突出自己的观点和想法。(此部分按照排名先后给分,约占总分的30%) 三、课程设计要求 1、实验目的 学会建立相应的运筹学模型 学会Excel、Lindo和WinQSB,QM for windows软件的基本使用方法 学会用Excel、Lindo和WinQSB,QM for windows软件得到问题的最优解 2、实验要求 分析问题、建立模型,并阐明建立模型的过程; 说明并显示软件使用和计算的详细过程与结果; 结果分析,将结果返回到实际问题进行分析、评价。 四、题目内容 (一)Excel规划求解基本实验 1、雅致家具厂生产4种小型家具,由于该四种家具具有不同的大小、形状、重量和风格,所以它们所需要的主要原料(木材和玻璃)、制作时间、最大销售量与利润均不相同。该厂每天可提供的木材、玻璃和工人劳动时间分别为600单位、1000单位与400小时,详细的数据资料见下表。问: (1)应如何安排这四种家具的日产量,使得该厂的日利润最大? (2)家具厂是否愿意出10元的加班费,让某工人加班1小时? (3)如果可提供的工人劳动时间变为398小时,该厂的日利润有何变化? (4)该厂应优先考虑购买何种资源?

STM32学习笔记_STM32F103ZET6

STM32F103 系列芯片的系统架构: 系统结构: 在每一次复位以后,所有除SRAM 和FLITF 以外的外设都被关闭,在使用一个外设之前,必须设置寄存器RCC_AHBENR 来打开该外设的时钟。

GPIO 输入输出,外部中断,定时器,串口。理解了这四个外设,基本就入门了一款MCU。 时钟控制RCC: -4~16M 的外部高速晶振 -内部8MHz 的高速RC 振荡器 -内部40KHz低速RC 振荡器,看门狗时钟 -内部锁相环(PLL,倍频),一般系统时钟都是外部或者内部高速时钟经过PLL 倍频后得到 - 外部低速32.768K 的晶振,主要做RTC 时钟源

ARM存储器映像: 数据字节以小端格式存放在存储器中。一个字里的最低地址字节被认为是该字的最低有效字节,而最高地址字节是最高有效字节。

存储器映像与寄存器映射: ARM 存储器映像 4GB 0X0000 00000X1FFF FFFF 0X2000 00000X3FFF FFFF 0X4000 00000X5FFF FFFF

寄存器说明: 寄存器名称 相对外设基地址的偏移值 编号 位表 读写权限 寄存器位 功能说明 使用C语言封装寄存器: 1、总线和外设基地址封装利用地址偏移 (1)定义外设基地址(Block2 首地址) (2)定义APB2总线基地址(相对外设基地址偏移固定) (3)定义GPIOX外设基地址(相对APB2总线基地址偏移固定)(4)定义GPIOX寄存器地址(相对GPIOX外设基地址偏移固定)(5)使用 C 语言指针操作寄存器进行读/写 //定义外设基地址 #define PERIPH_BASE ((unsigned int)0x40000000) 1) //定义APB2 总线基地址 #define APB2PERIPH_BASE (PERIPH_BASE + 0x00010000) 2) //定义GPIOC 外设基地址 #define GPIOC_BASE (AHB1PERIPH_BASE + 0x0800) 3) //定义寄存器基地址这里以GPIOC 为例 #define GPIOC_CRL *(unsigned int*)(GPIOC_BASE+0x00) 4) #define GPIOC_CRH *(unsigned int*)(GPIOC_BASE+0x04) #define GPIOC_IDR *(unsigned int*)(GPIOC_BASE+0x08) #define GPIOC_ODR *(unsigned int*)(GPIOC_BASE+0x0C) #define GPIOC_BSRR *(unsigned int*)(GPIOC_BASE+0x10) #define GPIOC_BRR *(unsigned int*)(GPIOC_BASE+0x14) #define GPIOC_LCKR *(unsigned int*)(GPIOC_BASE+0x18) //控制GPIOC 第0 管脚输出一个低电平5) GPIOC_BSRR = (0x01<<(16+0)); //控制GPIOC 第0 管脚输出一个高电平 GPIOC_BSRR = (0x01<<0);

stm32学习 c语言笔记

这是前段时间做彩屏显示时候遇到的难题, *(__IO uint16_t *) (Bank1_LCD_C)这个就是将后面的数据转换为地址,然后对地址单元存放数据。可如下等效: __IO uint16_t *addr; addr = (__IO uint16_t *) Bank1_LCD_C; #ifdef和#elif连用,语法和if。。。else if语句一样 推挽输出增加驱动,可以驱动LED起来 static int count=0 count++ 这个语句中,count仅仅被初始化一次 以后加加一次期中的值就不会变化了 SysTick_CTRL(控制和状态寄存器) SysTick_LOAD(重装载寄存器) SysTick_VAL(当前值寄存器) SysTick_CALIB(校准值寄存器)

TFT经验:弄多大的相片,必须先把那个相片的尺寸改掉,再去取模,才可以,要不会有重影的嘿嘿嘿嘿 VBAT 是电池供电的引脚 VBAT和ADD同时都掉电时才能让备份区复位。 volatile一个变量的存储单元可以在定义该变量的程序之外的某处被引用。 volatile主要是程序员要告诉编译器不要对其定义的这个变量进行优化,防止其不能被引用,不能被改变。 VDDA>2.4V ADC才能工作 VDDA>2.7V USB才能工作 VDD(1.8-3.6v) VBAT=1.8-3.6v VSS VSSA VREF必须接到地线 没有外部电源供电时必须VBAT接上VDD 使用PLL时,VDDA必须供电

printf("abs(x)=%d\n",x<0?(-1)*x:x) 条件编译是问号前边为真则取冒号前边的值,为假的,则取后边的值。 所以说上边这条打印的语句是打印x的绝对值。 //stm32f10x_nvic.c stm32f10x_lib.c stm32f10x_gpio.c stm32f10x_flash.c stm32f10x_rcc.c TIM6 TIM7基本定时器 (只有这两个定时器不能产生PWM) TIM1 TIM8高级控制定时器 TIM2 TIM3 TIM4 TIM5为通用定时器 其中高级定时器TIM1和TIM8可以同时产生多达7路的PWM输出。而通用定时器也能同时产生多达4路的PWM输出,这样,STM32最多可以同时产生30路PWM输出! 修改和自己写代码时候

MATLAB与在运筹学中的应用

MATLAB与在运筹学中的应用 摘要:论文通过MATLAB在运筹学中的应用实例,探讨了MATLAB在运筹学中的应用方法和技巧,初步了解matlab中优化工具箱的使用。 关键字:MATLAB应用运筹学优化计算 引言 运筹学是近代应用数学的一个分支,主要是研究如何将生产、管理等事件中出现的运筹问题加以提炼,然后利用数学方法进行解决的学科。运筹学是应用数学和形式科学的跨领域研究,利用像是统计学、数学模型和算法等方法,去寻找复杂问题中的最佳或近似最佳的解答。运筹学经常用于解决现实生活中的复杂问题,特别是改善或优化现有系统的效率。运筹学中常用的运算工具有Matlab、Mathematica、Maple、SAS 、SPSS、Lindo/Lingo、GAMS、WinQSB、Excel、其他,如SQP、DPS、ORS、Visual Decision、Decision Explore、AIMMS、Crystal等。 Matlab是矩阵实验室(Matrix Laboratory)的简称,是美国MathWorks公司出品的商业数学软件,和Mathematica、Maple并称为三大数学软件。 用于算法开发、数据可视化、数据分析以及数值计算的高级技术计算语言和交互式环境,主要包括Matlab和Simulink两大部分。 主要应用于工程计算、控制设计、信号处理与通讯、图像处理、信号检测、金融建模设计与分析等领域。 将matlab用于运筹学的最优化运算可以很好的解决优化问题,而且matlab 还专门有优化工具箱,是处理优化问题更加方便。 一、例:0-1规划(《运筹学》80页例3-9) 求minZ=x1-3*x2+6*x3+2*x4-4*x5 6*x1+2*x2-x3+7*x4+x5<=12 约束条件 x1+4*x2+5*x3-x4+3*x5>=10 Xj=0或1,j=1,2,3,4

STM32学习笔记

STM32学习笔记——时钟频率 ******************************** 本学习笔记基于STM32固件库V3.0 使用芯片型号:STM32F103 开发环境:MDK ******************************** 第一课时钟频率 STM32F103内部8M的内部震荡,经过倍频后最高可以达到72M。目前TI的M3系列芯片最高频率可以达到80M。 在stm32固件库3.0中对时钟频率的选择进行了大大的简化,原先的一大堆操作都在后台进行。系统给出的函数为SystemInit()。但在调用前还需要进行一些宏定义的设置,具体的设置在system_stm32f10x.c文件中。 文件开头就有一个这样的定义: //#define SYSCLK_FREQ_HSE HSE_Value //#define SYSCLK_FREQ_20MHz 20000000 //#define SYSCLK_FREQ_36MHz 36000000 //#define SYSCLK_FREQ_48MHz 48000000 //#define SYSCLK_FREQ_56MHz 56000000 #define SYSCLK_FREQ_72MHz 72000000 ST 官方推荐的外接晶振是8M,所以库函数的设置都是假定你的硬件已经接了8M 晶振来运算的.以上东西就是默认晶振8M 的时候,推荐的CPU 频率选择.在这里选择了: #define SYSCLK_FREQ_72MHz 72000000 也就是103系列能跑到的最大值72M 然后这个C文件继续往下看 #elif defined SYSCLK_FREQ_72MHz const uint32_t SystemFrequency = SYSCLK_FREQ_72MHz; const uint32_t SystemFrequency_SysClk = SYSCLK_FREQ_72MHz; const uint32_t SystemFrequency_AHBClk = SYSCLK_FREQ_72MHz; const uint32_t SystemFrequency_APB1Clk = (SYSCLK_FREQ_72MHz/2); const uint32_t SystemFrequency_APB2Clk = SYSCLK_FREQ_72MHz; 这就是在定义了CPU跑72M的时候,各个系统的速度了.他们分别是:硬件频率,系统时 钟,AHB总线频率,APB1总线频率,APB2总线频率.再往下看,看到这个了: #elif defined SYSCLK_FREQ_72MHz static void SetSysClockTo72(void); 这就是定义72M 的时候,设置时钟的函数.这个函数被SetSysClock ()函数调用,而SetSysClock ()函数则是被SystemInit()函数调用.最后SystemInit()函数,就是被你调用的了

运用线性规划对运输问题研究

运用线性规划对运输问题研究 班级:金融103班姓名:王纬福学号:5400210132摘要:由于企业选择运输路线或运输工具不合理而导致物流运输成本不能最小化的问题普遍存在而管理运筹学却能很好的解决此问题。通过科学的方法对问题进行具体化再建立数学模型并求解,就能找到运输成本最小的运输组合。 关键词:物流运输成本、输成本、管理运筹学、WinQSB2.0、线性规划 一、引言 日常生活中,人们经常需要将某些物品由一个空间位置移动到另一个空间位置,这就产生了运输。如何判定科学的运输方案,使运输所需的总费用最少,就是管理运筹学在运输问题上的运用需要解决的问题。 运输问题是一类应用广泛的特殊的线性规划问题,在线性规划的一般理论和单纯形法出现以前,康托洛维奇(L.V.Kant)和希奇柯克(F.L.Hitchcock)已经研究了运输问题。所以,运输问题又有“康-希问题”之称。对于运输问题(Transportation Problem TP)当然可用前面所讲的单纯形法求解,但由于该问题本身的特殊性,我们可以找到比标准单纯形法更简单有效的专门方法,从而节约计算时间和费用。主要是因为它们的约束方程组的系数矩阵具有特殊结构,使得这类问题的求解方法比常规的单纯形法要更为简便。 一、研究现状 运输问题的研究较多,并且几乎所有的线性规划书中都有论述。遗憾的是一些书中所建立的数学模型都不够全面和系统的。但是也有一些模型是严谨的没有漏洞和缺陷,并且很容易在此基础上修改或添加一些其他约束条件便于在实际工程中进行应用。管理运筹学在运输问题上的研究较为深入、全面、系统。对于计算机软件的引用也很前言,winQSB2.0对于普通甚至深入研究运输问题就已经是简单而又使用、耐用、好用的了。现在相关的杂志、期刊都越来越多关于管理运筹学,关于运输问题的文章论文初版,越来越得到重视。 二、文献回顾 随着物流行业和企业对物流运输要求的不断提高,企业的面临着更大的市场竞争,其运输活动在企业不断发展过程中,面临着越来越大难度的运输组合的选择决策问题。如何正确解决这个问题,是企业能够持续经营和发展不可忽视和必须面对的。这个问题同时也引起了企业界、学术界等社会各界的广泛关注。运输问题的实质是企业与运输组合的经济性问题,成功的企业通常都会面临如何选取最佳运输组合或运输路线这样一个重要问题,即以企业运输成本最小化作为确定最佳运输组合或运输路线的原落脚点。 四、案例分析 例:某公司下设生产同类产品的加工厂A1、A2、A3,生产的产品由4个销售点B1、B2、B3、B4出售。各工厂的生产量、各销售点的销量以及各工厂到各销售点的单位运价如下表:

STM32学习笔记(5)通用定时器PWM输出

STM32学习笔记(5):通用定时器PWM输出 2011年3月30日TIMER输出PWM 1.TIMER输出PWM基本概念 脉冲宽度调制(PWM),是英文“Pulse Width Modulation”的缩写,简称脉宽调制,是利用微处理器的数字输出来对模拟电路进行控制的一种非常有效的技术。简单一点,就是对脉冲宽度的控制。一般用来控制步进电机的速度等等。 STM32的定时器除了TIM6和TIM7之外,其他的定时器都可以用来产生PWM输出,其中高级定时器TIM1和TIM8可以同时产生7路的PWM输出,而通用定时器也能同时产生4路的PWM输出。 1.1PWM输出模式 STM32的PWM输出有两种模式,模式1和模式2,由TIMx_CCMRx寄存器中的OCxM位确定的(“110”为模式1,“111”为模式2)。模式1和模式2的区别如下: 110:PWM模式1-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为无效电平(OC1REF=0),否则为有效电平(OC1REF=1)。 111:PWM模式2-在向上计数时,一旦TIMx_CNTTIMx_CCR1时通道1为有效电平,否则为无效电平。 由此看来,模式1和模式2正好互补,互为相反,所以在运用起来差别也并不太大。 而从计数模式上来看,PWM也和TIMx在作定时器时一样,也有向上计数模式、向下计数模式和中心对齐模式,关于3种模式的具体资料,可以查看《STM32参考手册》的“14.3.9 PWM模式”一节,在此就不详细赘述了。 1.2PWM输出管脚 PWM的输出管脚是确定好的,具体的引脚功能可以查看《STM32参考手册》的“8.3.7 定时器复用功能重映射”一节。在此需要强调的是,不同的TIMx有分配不同的引脚,但是考虑到管脚复用功能,STM32提出了一个重映像的概念,就是说通过设置某一些相关的寄存器,来使得在其他非原始指定的管脚上也能输出PWM。但是这些重映像的管脚也是由参考手册给出的。比如

STM32学习笔记

1、GPIO函数: 输出: HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_RESET);//此例以PA12口为例 HAL_GPIO_WritePin(GPIOA, GPIO_PIN_12, GPIO_PIN_SET); //此例以PA12口为例 HAL_GPIO_ TogglePin(GPIOA,GPIO_PIN_12); //此例以PA12口为例 2、串口函数: 1、串口发送/接收函数 HAL_UART_Transmit();串口轮询模式发送,使用超时管理机制 HAL_UART_Receive();串口轮询模式接收,使用超时管理机制 HAL_UART_Transmit_IT();串口中断模式发送 HAL_UART_Receive_IT();串口中断模式接收 HAL_UART_Transmit_DMA();串口DMA模式发送 HAL_UART_Transmit_DMA();串口DMA模式接收 2、串口中断函数 HAL_UART_TxHalfCpltCallback();一半数据发送完成时调用 HAL_UART_TxCpltCallback();数据完全发送完成后调用 HAL_UART_RxHalfCpltCallback();一半数据接收完成时调用 HAL_UART_RxCpltCallback();数据完全接受完成后调用 HAL_UART_ErrorCallback();传输出现错误时调用 例程:串口接收中断 uint8_t aTxStartMessages[] = "\r\n******UART commucition using IT******\r\nPlease enter 10 characters:\r\n"; uint8_t aRxBuffer[20]; 2、在main函数中添加两个语句通过串口中断发送aTxStartMessage数组的数据和接收数据10个字符,保存在数组aRxBuffer中 HAL_UART_Transmit_IT(&huart1 ,(uint8_t*)aTxStartMessages,sizeof(aTxStartMessages)); //sizeof()可读取目标长度 HAL_UART_Receive_IT(&huart1,(uint8_t*)aRxBuffer,10); 3、在main.c文件后面添加中断接收完成函数,将接收到的数据又通过串口发送回去。 void HAL_UART_RxCpltCallback(UART_HandleTypeDef *huart) { UNUSED(huart); HAL_UART_Transmit(&huart1,(uint8_t*)aRxBuffer,10,0xFFFF);//(uint8_t*)aRxBuffer为字符串地址,10为字符串长度,0xFFFF为超时时可以在中间加任何可执行代码。 }

winqsb使用方法

实验一WinQSB的基本操作 一、实验目的 了解WinQSB软件基本构成、运行界面和基本操作方法,使学生能基本掌握WinQSB 软件常用命令和功能。了解WinQSB软件在Windows环境下的文件管理操作。 二、实验平台和环境 WinQSB是QSB的Windows版本,可以在Windows9X/ME/NT/2000/XP平台下运行。WinQSB V1.0共有19个子系统,分别用于解决运筹学不同方面的问题,详见表1-1。 表1-1

三、实验内容和要求 1.学会WinQSB的安装和启动方法 2.熟悉WinQSB的界面和各项基本操作 3.能用WinQSB软件与office文档交换数据。 四、实验操作步骤 1.4.1安装 WinQSB的安装比较简单。双击Setup.exe,弹出窗口如图1-1所示: 图1-1 输入要安装到哪个目录,点Continue按钮,弹出窗口如图1-2所示:

图1-2 输入用户名和公司或组织名称,点Continue按钮进行文件的复制,完成后弹出窗口如图1-3: 图1-3 显示安装完成,点“确定”退出。 WinQSB软件安装完毕后,会在开始→程序→WinQSB中生成19个菜单项,分别对应运筹学的19个问题。如图1-4所示:

图1-4 具体功能见表1-1。 针对不同的问题,选择不同的子菜单项,运行相应的程序,然后使用File菜单下的New Problem菜单来输入所需数据。 1.4.2运行 WinQSB基本上有三种窗口:启动窗口、数据输入窗口、结果输出窗口。现以Linear and Integer Programming为例加以说明: 1.启动窗口。在开始菜单中选择Linear and Integer Programming,运行后出现启动窗口如下图1-5所示: 图1-5 (1)标题栏:显示了程序的名称。 (2)菜单栏:共有两个菜单:File和Help。 File菜单只有三个子菜单:New Problem、Load Problem和Exit。 New Problem:创建新问题 Load Problem:装载问题 Exit:退出

STM32学习心得笔记

STM32学习心得笔记 时钟篇 在STM32中,有五个时钟源,为HSI、HSE、LSI、LSE、PLL。 ①、HSI是高速内部时钟,RC振荡器,频率为8MHz。 ②、HSE是高速外部时钟,可接石英/陶瓷谐振器,或者接外部时钟源,频率范围为 4MHz~16MHz。 ③、LSI是低速内部时钟,RC振荡器,频率为40kHz。 ④、LSE是低速外部时钟,接频率为32.768kHz的石英晶体。 ⑤、PLL为锁相环倍频输出,其时钟输入源可选择为HSI/2、HSE或者HSE/2。倍频可选择为2~16倍, 但是其输出频率最大不得超过72MHz。 其中40kHz的LSI供独立看门狗IWDG使用,另外它还可以被选择为实时时钟RTC的时钟源。另外, 实时时钟RTC的时钟源还可以选择LSE,或者是HSE的128分频。RTC的时钟源通过RTCSEL[1:0]来选择。 STM32中有一个全速功能的USB 模块,其串行接口引擎需要一个频率为48MHz的时

钟源。该时钟源只能 从PLL输出端获取,可以选择为1.5分频或者1分频,也就是,当需要使用USB模块时,PLL 必须使能, 并且时钟频率配置为48MHz或72MHz。 另外,STM32还可以选择一个时钟信号输出到MCO脚(PA8)上,可以选择为PLL输出的2分频、HSI、HSE、或者系统时钟。 系统时钟SYSCLK,它是供STM32中绝大部分部件工作的时钟源。系统时钟可选择为PLL 输出、HSI或者HSE。系统时钟最 大频率为72MHz,它通过AHB分频器分频后送给各模块使用,AHB分频器可选择1、2、4、8、16、64、128、256、512分 频。其中AHB分频器输出的时钟送给5大模块使用: ①、送给AHB 总线、内核、内存和DMA使用的HCLK时钟。 ②、通过8分频后送给Cortex的系统定时器时钟。 ③、直接送给Cortex的空闲运行时钟FCLK。 ④、送给APB1分频器。APB1分频器可选择1、2、4、8、16分频,其输出一路供APB1外设使用(PCLK1,最大频率36MHz), 另一路送给定时器(Timer)2、3、4倍频器使用。该倍频器可选择1或者2倍频,时钟输出供定时器2、3、4使用。

运筹学在配料问题中的应用 C-2

运筹学在配料问题中的应用 罗启川(1015030003),徐立飞(1015030129),龙雪松(1015030065)【西昌学院 工程技术学院 10级水利水电1班,四川 西昌 615013】 【摘 要】本文是通过对运筹学在配料问题中的应用进行分析研究,解决配料 问题中最低成本的最优配料方案。通过对数据的分析与建模,经过软件WinQSB 的数据处理,得到最低成本的最优配料方案。本文运用运筹学对最低成本下最优配料的影响,掌握运筹学的基本概念、基本原理、基本方法和解题技巧,对于一些简单的问题可以根据实际问题建立运筹学模型及求解模型,最终通过WinQSB 软件得出结论。 【关键词】运筹学 配料问题 WinQSB 软件 灵敏度分析 通过对此次对运筹学的学习我掌握了运筹学的基本概念、基本原理、基本方 法和解题技巧,并掌握了WinQSB 软件,对于一些简单的问题可以根据实际问题建立运筹学模型及求解模型。运筹学对我们以后的生活也将有不小的影响,下面将运筹学运用到实际问题上学以致用。 一、问题描述 【案例C-2】配料问题 某饲料公司生产肉用种鸡配合饲料,每千克饲料所需营养质量要求如表C -4所示。 表C-4 : 公司计划使用的原料有玉米,小麦, 麦麸,米糠,豆饼,菜子饼,鱼粉,槐叶粉,DL-蛋氨酸,骨粉,碳酸钙和食盐等12种原料。各原料的营养成分含量及价格见表C -5。 表C-5 :

公司根据原料来源,还要求1吨配合饲料中原料的含量为:玉米不低于400 kg,小麦不低于100 kg,麦麸不低于100 kg,米糠不超过150 kg,豆饼不超过100 kg,菜子饼不低于30 kg,鱼粉不低于50 kg,槐叶粉不低于30 kg,DL-蛋氨酸,骨粉,碳酸钙适量。(1)按照肉用种鸡公司标准,求1千克配合饲料中每种原料各配多少成本最低,建立数学模型并求解。 (2)按照肉用种鸡国家标准,求1千克配合饲料中每种原料各配多少成本最低。 (3)公司采购了一批花生饼,单价是0.6元/kg,代谢能到有机磷的含量分别(2.4,38,120,0,0.92,0.15,0.17),求肉用种鸡成本最低的配料方案。(4)求产蛋鸡的最优饲料配方方案。(5)公司考虑到未来鱼粉、骨粉和碳酸钙将要涨价,米糠将要降价,价格变化率都是原价的r %。试对两种产品配方方案进行分析。 说明:以上5个问题独立求解和分析,如在问题(3)中只加花生饼,其它方案则不加花生饼。 二、建模分析 (1)按照肉用种鸡公司标准,求1千克配合饲料中每种原料各配多少成本最低,建立数学模型并求解。由题目要求可知,目标是求成本的最小最优值,根据表C-4中每千肉用种鸡公司标准饲料所需营养质量要求含量数据和表C-5中提供的原材料价格数据, 设每千饲料所含各种原材料为x j ,Z表 示成本,Z= xj cj*且x j>=0,j=1,2……12。根据公司对玉米、小麦、麦 麸、米糠、豆饼、菜子饼、鱼粉、槐 叶粉八种原料的要求,在这个问题中 x 1 >=0.4,x 2 >=0.1,x 3 >=0.1,x 4 <=0.15, x 5 <=0.1,x 6 >=0.03,x 7 >=0.05, x 8 >=0.03,因此这个问题的数学模型可 归纳为: minZ=0.68*x1+0.72*x2+0.23*x3+0.2 2*x4+0.37*x5+0.32*x6+1.54*x7+0.3 8*x8+23*x9+0.56*x10+1.12*x11+0.4 2*x12; ① 3.35*x1+3.08*x2+1.78*x3+2.1*x4+2 .4*x5+1.62*x6+2.8*x7+1.61*x8>=2. 7 ② 78*x1+114*x2+142*x3+117*x4+402*x 5+360*x6+450*x7+170*x8>=135 ③ 78*x1+114*x2+142*x3+117*x4+402*x 5+360*x6+450*x7+170*x8<=145 ④ 16*x1+22*x2+95*x3+72*x4+49*x5+11 3*x6+108*x8<=45 ⑤ 2.3*x1+ 3.4*x2+6*x3+6.5*x4+2 4.1*x 5+8.1*x6+29.1*x7+10.6*x8>=5.6 ⑥ 1.2*x1+1.7*x2+ 2.3*x3+2.7*x4+5.1*x5 +7.1*x6+11.8*x7+2.2*x8+980*x9>=2.6 ⑦ 0.7*x1+0.6*x2+0.3*x3+1*x4+3.2*x5 +5.3*x6+63*x7+4*x8+300*x10+400*x 11>=30

STM32学习笔记(18)-数据的保存和毁灭

数据的保存和毁灭(2) 和以前学到的有关数据保存不同,这里的数据保存还有“保密”之意,即一旦受到意外的侵入,STM32将毁灭数据。这是通过Tamper机制来实现的。 以下是数据手册中的有关说明: 5.3.1 侵入检测 当TAMPER引脚上的信号从0变成1或者从1变成0(取决于备份控制寄存器BKP_CR的TPAL 位),会产生一个侵入检测事件。侵入检测事件将所有数据备份寄存器内容清除。然而为了避免丢失侵入事件,侵入检测信号是边沿检测的信号与侵入检测允许位的逻辑与,从而在侵入检测引脚被允许前发生的侵入事件也可以被检测到。 ●当 TPAL=0 时:如果在启动侵入检测TAMPER引脚前(通过设置TPE位)该引脚已经为高电平,一旦启动侵入检测功能,则会产生一个额外的侵入事件(尽管在TPE位置’1’后并没有出现上升沿)。 ●当 TPAL=1 时:如果在启动侵入检测引脚TAMPER前(通过设置TPE位)该引脚已经为低电平,一旦启动侵入检测功能,则会产生一个额外的侵入事件(尽管在TPE位置’1’后并没有出现下降沿)。 设置BKP_CSR寄存器的TPIE位为’1’,当检测到侵入事件时就会产生一个中断。 在一个侵入事件被检测到并被清除后,侵入检测引脚TAMPER应该被禁止。然后,在再次写入备份数据寄存器前重新用TPE位启动侵入检测功能。这样,可以阻止软件在侵入检测引脚上仍然有侵入事件时对备份数据寄存器进行写操作。这相当于对侵入引脚TAMPER进行电平检测。 注:当V DD电源断开时,侵入检测功能仍然有效。为了避免不必要的复位数据备份寄存器,TAMPER引脚应该在片外连接到正确的电平。 显然,Tamper需要硬件与之配合。以上数据手册描述了硬件配置时的一些注意事项。 (1)可以是把引脚由低电平到高电平认为是一次侵入,也可以把引脚从高电平变到低电平认为是一次侵入,这通过TPAL来设置。

STM32自学笔记

一、原子位操作: 原子位操作定义在文件中。令人感到奇怪的是位操作函数是对普通的内存地址进行操作的。原子位操作在多数情况下是对一个字长的内存访问,因而位号该位于0-31之间(在64位机器上是0-63之间),但是对位号的范围没有限制。 原子操作中的位操作部分函数如下: void set_bit(int nr, void *addr)原子设置addr所指的第nr位 void clear_bit(int nr, void *addr)原子的清空所指对象的第nr位 void change_bit(nr, void *addr)原子的翻转addr所指的第nr位int test_bit(nr, void *addr)原子的返回addr位所指对象nr位int test_and_set_bit(nr, void *addr)原子设置addr所指对象的第nr位,并返回原先的值 int test_and_clear_bit(nr, void *addr)原子清空addr所指对象的第nr位,并返回原先的值 int test_and_change_bit(nr, void *addr)原子翻转addr所指对象的第nr位,并返回原先的值 unsigned long word = 0; set_bit(0, &word); /*第0位被设置*/ set_bit(1, &word); /*第1位被设置*/ clear_bit(1, &word); /*第1位被清空*/ change_bit(0, &word); /*翻转第0位*/ 二、STM32的GPIO锁定: 三、中断挂起: 因为某种原因,中断不能马上执行,所以“挂起”等待。比如有高、低级别的中断同时发生,就挂起低级别中断,等高级别中断程序执行完,在执行低级别中断。四、固文件: 固件(Firmware)就是写入EROM(可擦写只读存储器)或EEPROM(电可擦可编程只读存储器)中的程序。 五、固件库:包含各个外设或者内核的驱动头文件和C文件。 六、TIx的输入捕获滤波器(消抖): 采样频率fSAMPLING,采样次数N,如果以采样频率对一脉冲进行采样时,如果在N个采样方波里该脉宽不变,则视为一次有效的脉冲,否则视为无效的脉冲。 七、高级定时器的PWM互补输出: 常用于X相电机驱动,其中的互补输出则防止电机的死区出现。

线性规划在运输问题中的应用

线性规划在运输问题中的应用 摘要:运输问题是运筹学和物流管理中非常重要的一个分支。为了令企业更快更好地编制运输方案,既能满足实际需求而又使总费用最少,提出了如何利用现有资源实现运输的最优化控制问题,通过实例以及运用WinQSB2.0软件包进行计算机模拟仿真计算,说明该问题研究的科学性、可靠性及其应用价值,,实现运输问题最优化求解的程序化运行。这样既缩短了运输公司对货物数量分配的研究时间,又为运输问题的决策提供了可靠的理论和实践指导。 关键词:运输问题数学模型线性代数表上作业法WinQSB2.0 一、引言 对企业来说,生产决策的主要目标是:在现有条件下,如何最有效地利用人力、物力、财力等各种资源,以取得最大的经济效益。[2]在物资短缺年代,企业可以靠扩大产量、降低制造成本去攫取第一利润。在物资丰富的年代,企业又可以通过扩大销售攫取第二利润。可是在新世纪和新经济社会,第一利润源和第二利润源已基本到了一定极限,目前剩下的一"未开垦的处女地"就是运输。降价是近几年家电行业企业之间主要的竞争手段,降价竞争的后盾是企业总成本的降低,即功能、质量、款式和售后服务以外的成本降价,也就是降低运输成本。 国外的制造企业很早就认识到了货运是企业竞争力的法宝,搞好运输可以实现零库存、零距离和零流动资金占用,是提高为用户服务,构筑企业供应链,增加企业核心竞争力的重要途径。在经济全球化、信息全球化和资本全球化的21世纪,企业只有建立现代货物运输结构,才能在激烈的竞争中,求得生存和发展。在此,运输对企业的重要性可窥一斑。 日常生活中,人们经常需要将某些物品由一个空间位置移动到另一个空间位置,这就产生了运输,如何判定科学的方案,使运输所需的总费用最少,就是运输的最优化决策问题。运输的最优化决策问题可以建立相应的数学模型,即通过数学运算进行解决。 二、研究现状 虽然表上作业法是简便、明了而有效,但是这个模型所得出的数据仅符合理想状态下,因为它考虑到的因素只有产地的数目、各产地的产量、销地的数目和个销地的销量,它没有真正地将货物在运输过

STM32学习LCD的显示

STM32学习LCD的显示 1.LCD/LCM的基本概念 液晶显示器(Liquid Crystal Display: LCD)的构造是在两片平行的玻璃当中放置液态的晶体,两片玻璃中间有许多垂直和水平的细小电线,透过通电与否来控制杆状水晶分子改变方向,将光线折射出来产生画面。 LCM(LCD Module)即LCD显示模组、液晶模块,是指将液晶显示器件,连接件,控制与驱动等外围电路,PCB电路板,背光源,结构件等装配在一起的组件。 在平时的学习开发中,我们一般使用的是LCM,带有驱动IC和LCD屏幕等多个模块。 2.FSMC的基本概念 在STM32上开发LCD显示,可以有两种方式来对LCD进行操作,一种是通过普通的IO 口,连接LCM的相应引脚来进行操作,第2种是通过FSMC来进行操作。 可变静态存储控制器(Flexible Static Memory Controller: FSMC) 是STM32系列中内部集成256 KB以上FlaSh,后缀为xC、xD和xE的高存储密度微控制器特有的存储控制机制。之所以称为“可变”,是由于通过对特殊功能寄存器的设置,FSMC能够根据不同的外部存储器类型,发出相应的数据/地址/控制信号类型以匹配信号的速度,从而使得STM32系列微控制器不仅能够应用各种不同类型、不同速度的外部静态存储器,而且能够在不增加外部器件的情况下同时扩展多种不同类型的静态存储器,满足系统设计对存储容量、产品体积以及成本的综合要求。 FSMC有很多优点: 1.支持多种静态存储器类型。STM32通过FSMC可以与SRAM、ROM、PSRAM、NOR Flash和NANDFlash存储器的引脚直接相连。 2.支持丰富的存储操作方法。FSMC不仅支持多种数据宽度的异步读/写操作,而且支持对NOR、PSRAM、NAND存储器的同步突发访问方式。 3.支持同时扩展多种存储器。FSMC的映射地址空间中,不同的BANK是独立的,可用于扩展不同类型的存储器。当系统中扩展和使用多个外部存储器时,FSMC会通过总线悬空延迟时间参数的设置,防止各存储器对总线的访问冲突。 4.支持更为广泛的存储器型号。通过对FSMC的时间参数设置,扩大了系统中可用存储器的速度范围,为用户提供了灵活的存储芯片选择空间。 5.支持代码从FSMC扩展的外部存储器中直接运行,而不需要首先调入内部SRAM。FSMC包含两类控制器: 1.1个NOR闪存/SRAM控制器,可以与NOR闪存、SRAM和PSRAM存储器接口。 2.1个NAND闪存/PC卡控制器,可以与NAND闪存、PC卡,CF卡和CF+存储器接口。控制器产生所有驱动这些存储器的信号时序: 1.16位数据线,用于连接8位或16位的存储器; 2.26位地址线,最多可连续64MB的存储器(这里不包括片选线); 3.5位独立的片选信号线; 4.1组适合不同类型存储器的控制信号线: -控制读/写操作 -与存储器通信,提供就绪/繁忙信号和中断信号 -与所用配置的PC卡接口:PC存储卡、PC I/O卡和真正的IDE接口 从FSMC的角度看,可以把外部存储器划分为固定大小为256MB的4个存储块 · 存储块1用于访问最多4个NOR闪存或者PSRAM存储设备。这个存储区被划分为4个

实验五 运输与指派问题

实验五运输与指派问题 一、实验目的 熟悉WinQSB软件LP-ILP子系统界面内容,掌握操作命令。用WinQSB软件求解运输与指派问题。 二、实验平台和环境 Windows9X/ME/NT/2000/XP平台下,WinQSB V1.0版本已经安装在D:\WinQSB中。 三、实验内容和要求 建立运输与指派新问题,使用WinQSB软件输入模型,求解模型,并对问题的结果进行简单分析。 四、实验操作步骤 5.4.1 求解运输与指派问题。启动程序,点击开始→程序→WinQSB→Network Modeling。 5.4.2 分析例题。点击File→Load Problem打开磁盘中的数据文件,Network Modeling 程序自带后缀“.NET”的7个典型例题,供学习参考。 其中第一个例题https://www.sodocs.net/doc/0718475687.html,为指派问题的例题,第六个例题https://www.sodocs.net/doc/0718475687.html,为运输问题的例题,下面分别打开这两个问题加以分析。 1. 运输问题:打开https://www.sodocs.net/doc/0718475687.html,文件,分析运输问题的求解步骤。系统显示如图5-1所示的界面。 图5-1 运输问题的例题 点击菜单栏Solve and Analyze→Solve the Problem或点击工具栏中的图标,即可得到本例题的最优解——如表5-1的计算结果。最小支付运费为3350。 表5-1 例题https://www.sodocs.net/doc/0718475687.html,的计算结果 如果点击菜单栏Solve and Analyze→Solve and Display Steps-Tableau,可以显示表上作业法的解题迭代步骤,观察一下软件用表上作业法求解运输问题的步骤。

第一步得到如图5-2的计算结果。 图5-2 Transportation Iteration 1 再点图标,第二步得到如图5-3的计算结果。 图5-3 Transportation Iteration 2

相关主题