This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

[参考译文] LM8330:PWM不想工作

Guru**** 2390755 points
Other Parts Discussed in Thread: LM8330

请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1098467/lm8330-pwm-just-doesn-t-want-to-work

部件号:LM8330

我的问题是LM8330的PWM0的功能。
我正在为我们的一款产品开发一个5x10键盘驱动程序,它基于lm8330组件,使用来发出事件信号,KPY11列上的中断在矩阵中没有使用。
此外,我需要在其他KPY10列上使用PWM0,键盘也不使用PWM0,用于蜂鸣器或背光调节。
键盘工作正常,而PWM0只是不想工作。
我附加了用于初始化lm8330组件的源代码。 我想澄清的是,我在论坛上发现了我感兴趣的任何话题,但这还不足以使我的问题得到理解。
在论坛上,我还发现在编写PWM脚本的字模式的方法上有许多不准确之处。 有时,写入顺序报告为第一个LSB,然后是MSB,有时报告为第一个MSB,然后是LSB。
我认为它应该是MSB,然后是LSB,连续写入。 至少我希望。
在所附的源代码中有3个脚本,但没有任何脚本(如注释中所示)按预期工作。
我绝望了,因为我在各种组合中进行了无休止的测试,但没有任何积极的结果。
只有一件事需要报告,在键盘上。 我不得不重复命令“CLKMODE”来设置“操作模式”,否则键盘不工作,就好像在键盘编程中有一些指令一样,将其置于睡眠模式。
感谢那些能帮我的人。

#define LM8330_CMD_SET_KBDSETTLE	0x01 /* Set KBDSETTLE time. Initial time for keys to settle, before the key-scan process is started*/
#define LM8330_CMD_SET_KBDBOUNCE	0x02 /* Set debouncing time. */
#define LM8330_CMD_SET_KBDSIZE		0x03 /* Set keypad size. Defines the physical keyboard matrix size*/
#define LM8330_CMD_SET_KBDDEDCFG	0x04 /* Set Dedicated Key Register. Defines if a key is used as a standard keyboard/GPIO pin or whether it is used as dedicated key input*/
#define LM8330_CMD_SET_KBDDEDCFG0	0x04 /* Set Dedicated Key Register. Defines if a key is used as a standard keyboard/GPIO pin or whether it is used as dedicated key input*/
#define LM8330_CMD_SET_KBDDEDCFG1	0x05 /* Set Dedicated Key Register. Defines if a key is used as a standard keyboard/GPIO pin or whether it is used as dedicated key input*/
#define LM8330_CMD_READ_KBDRIS		0x06 /* Get Keyboard Raw Interrupt Status register. Returns the status of stored keyboard interrupts*/
#define LM8330_CMD_READ_KINT		0x06
#define LM8330_CMD_READ_KBDMIS		0x07 /* Get Keypad Masked Interrupt Status Register. Returns the status on masked keyboard interrupts after masking with the KBDMSK register*/
#define LM8330_CMD_SET_KBDIC		0x08 /* Set Keypad Interrupt Clear Register. Setting these bits clears Keypad active Interrupts */
#define LM8330_CMD_SET_KBDMSK		0x09 /* Set Keypad Interrupt Mask Register. Configures masking of keyboard interrupts. Masked interrupts do not trigger an event on the Interrupt output */
#define LM8330_CMD_READ_KBDCODE0	0x0B /* Read the first detected key. */
#define LM8330_CMD_READ_KBDCODE1	0x0C /* Read the second detected key. */
#define LM8330_CMD_READ_KBDCODE2	0x0D /* Read the third detected key. */
#define LM8330_CMD_READ_KBDCODE3	0x0E /* Read the forth detected key. */
#define LM8330_CMD_READ_EVTCODE		0x10 /* KRead key Event from Code Register */

#define LM8330_CMD_SET_TIMCFG0		0x60 /* Set PWM Timer 0 Configuration Register. This register configures interrupt masking of the associated PWM channel*/
#define LM8330_CMD_SET_PWMCFG0		0x61 /* Set PWM Timer 0 Conf iguration Control Register. This register defines interrupt masking and the output behavior for the associated PWM channel */
#define LM8330_CMD_SET_PWMCFG1		0x69 /* Set PWM Timer 1 Conf iguration Control Register. This register defines interrupt masking and the output behavior for the associated PWM channel */
#define LM8330_CMD_SET_PWMCFG2		0x71 /* Set PWM Timer 2 Conf iguration Control Register. This register defines interrupt masking and the output behavior for the associated PWM channel */
#define LM8330_CMD_SET_TIMSWRES		0x78 /* Set PWM Timer Software Reset Registers. Reset control on all PWM timers */
#define LM8330_CMD_READ_TIMRIS		0x7A /* Read PWM Timer Interrupt Status Register. This register returns the raw interrupt status from the PWM timers 0,1 and 2.*/
#define LM8330_CMD_READ_TIMMIS		0x7B /* Read PWM Timer Masked Interrupt Status Register. This register returns the masked interrupt status from the PWM timers 0, 1 and 2. */
#define LM8330_CMD_SET_TIMIC		0x7C /* Set PWM Timer Interrupt Clear Register. This register clears timer and pattern interrupts. */
#define LM8330_CMD_SET_PWMWP		0x7D /* Set PWM Timer Pattern Pointer Register. Pointer to the pattern position inside the configuration register, which will be overwritten by the next write access to be PWMCFG register */
#define LM8330_CMD_SET_PWMCFG		0x7E /* PWM Script Register. Two-byte pattern storage register for a PWM script command indexed by PWMWP. PWMWP is automatically incremented*/
#define LM8330_CMD_SET_I2CSA		0x80 /* Set Slave Address Register. The address is internally applied after the next I2C STOP*/
#define LM8330_CMD_READ_MFGCODE		0x80 /* Read Manufacturer Code Register*/
#define LM8330_CMD_READ_SWREV		0x81 /* Read Software revision code of the LM8330 */
#define LM8330_CMD_SWRESET			0x81 /* Software Reset Register. The reset is only applied if the supplied parameter has the inverted value as SWBIT*/
#define LM8330_CMD_RSTCTRL			0x82 /* Software reset of specific parts of the LM8330 */
#define LM8330_CMD_RSTINTCLR		0x84 /* Clear NO Init/Power-On Interrupt Register . This register is used to clear the PORIRQ Interrupt. This interrupt is set every time the device returns from RESET (either POR, HW or SW Reset).*/

#define LM8330_CMD_CLKMODE			0x88 /* Clock Mode Register. This register controls the current operating mode of the LM8330 device. */
#define LM8330_CMD_CLKEN			0x8A /* Clock Enable Register. Controls the clock to different functional units. It is used to enable the functional blocks globally and independently */
#define LM8330_CMD_AUTOSLP			0x8B /* Auto-sleep Enable Register. This register controls the Auto-Sleep function of the LM8330 device */
#define LM8330_CMD_AUTOSLPTIL		0x8C /* Auto-Sleep Time Register Low byte. This register defines the activity time. If this time passes without any processing events then the device enters into sleep-mode, but only if AUTOSLP.ENABLE bit is set to 1. */
#define LM8330_CMD_AUTOSLPTIH		0x8D /* Auto-Sleep Time Register High byte*/

#define LM8330_CMD_READ_IRQST		0x91 /* Read Interrupt Global Interrupt Status Register. Returns the interrupt status from various on-chip function blocks */
#define LM8330_CMD_READ_INT			0x91

#define LM8330_CMD_SET_IOCFG		0xA7 /* Input/Output Pin Mapping Configuration Register. Configures usage of KPY[11:8] if not used for Keypad. */
#define LM8330_CMD_SET_IOPC0		0xAA /* Pull Resistor Configuration Register 0. Defines the pull resistor configuration for balls KPX[7:0]. */
#define LM8330_CMD_SET_IOPC1		0xAC /* Pull Resistor Configuration Register 1. Defines the pull resistor configuration for balls KPY[7:0].. */
#define LM8330_CMD_SET_IOPC2		0xAE /* Pull Resistor Configuration Register 2. Defines the pull resistor configuration for balls KPY[11:8].. */



/* Interrupt global status. */
#define INT_GPIOIRQ					0x01 /* GPIO interrupt */
#define INT_TIM0IRQ					0x02 /* Timer0 expiry */
#define INT_TIM1IRQ					0x04 /* Timer0 expiry */
#define INT_TIM2IRQ					0x08 /* Timer0 expiry */
#define INT_KBDIRQ					0x40 /* Keyboard interrupt (further key selection in keyboard module */
#define INT_PORIRQ					0x80 /* Supply failure on VCC. Also power-on is considered as an initial supply failure */ 

/* Keyboard Row Interrupt status. */
#define KINT_RSINT					0x01 /* Raw scan interrupt.Interrupt generated after keyboard scan, if the keyboard status has changed. */
#define KINT_RKLINT					0x02 /* Raw key lost interrupt indicates a lost key-code. */
#define KINT_REVTINT				0x04 /* Raw keyboard event interrupt.At least one key press or key release is in the keyboard event buffer */
#define KINT_RELINT					0x08 /* Raw event lost interrupt. More than 16 keyboard events have been detected and caused the event buffer to overflow */


/* Clock settings (CMD_CLKMODE). */
#define CLK_MODCTL					0x01 /* 00: SLEEP Mode, 01: Operation Mode .Writing to 00 forces the device to immediately enter sleep mode,*/

/* Clock settings (CMD_CLKEN). */
#define CLK_TIMEN					0x04 /* PWM Timer 0, 1, 2 clock enable */
#define CLK_KBDEN					0x01 /* Keyboard clock enable (enables/disables key scan) */

#define SCRIPT_1
//#define SCRIPT_2
//#define SCRIPT_3

static int lm8330_configure(struct lm8330_chip *lm)
{
	int keysize = (lm->size_x << 4) | lm->size_y;
	int clock = (CLK_TIMEN | CLK_KBDEN);
	int debounce = lm->debounce_time >> 2;
	int active = lm->active_time >> 2;

	/*
	 * Active time must be greater than the debounce time: if it's
	 * a close-run thing, give ourselves a 12ms buffer.
	 */
	if (debounce >= active)
		active = debounce + 3;

	lm8330_write(lm, 2, LM8330_CMD_AUTOSLP, 0x00);				/* disable autoslip */
	lm8330_write(lm, 2, LM8330_CMD_CLKMODE, 0x01);				/* set Operation mode */
	lm8330_write(lm, 2, LM8330_CMD_CLKEN, clock);				/* nable keyboard clock end timers */
	
	lm8330_write(lm, 2, LM8330_CMD_SET_KBDSETTLE, 0x80);		/* Set the keyscan settle time to 12 msec. */
	lm8330_write(lm, 2, LM8330_CMD_SET_KBDBOUNCE, debounce);	/* Set the keyscan debounce time */
	lm8330_write(lm, 2, LM8330_CMD_SET_KBDSIZE, keysize);		/* Set the keyscan matrix size to 5 rows x 10 columns */
	lm8330_write(lm, 3, LM8330_CMD_SET_KBDDEDCFG, 0xFF, 0xFF);	/* Confirm default value */


	lm8330_write(lm, 2,LM8330_CMD_SET_IOCFG, 0x11);				/* KPY10-> pwm, KPY11->IRQ */

	lm8330_write(lm, 3,LM8330_CMD_SET_IOPC0, 0xAA, 0xAA);		/* pull up resistor for row*/
	lm8330_write(lm, 3,LM8330_CMD_SET_IOPC1, 0x55, 0x55);		/* pulldown resistor for column 0-7*/
	lm8330_write(lm, 3,LM8330_CMD_SET_IOPC2, 0x5A, 0x05);		/* pulldown resistor for column 8-9*/

	lm8330_write(lm, 2,LM8330_CMD_RSTINTCLR, 0x01); 			/* Clear Power On interrupt */

	lm8330_write(lm, 2,LM8330_CMD_SET_KBDIC, 0x03); 			/* Clear all pending interrupts */

	lm8330_write(lm, 2,LM8330_CMD_SET_KBDMSK, 0x0B); 			/* Configure interrupt masking */

	/* PWM0 programming
	 *
	 */

	lm8330_write(lm, 2, LM8330_CMD_SET_TIMCFG0, 0x10);			/* Interrupt mask for PWM CYCIRQ0 */
	lm8330_write(lm, 2, LM8330_CMD_SET_PWMCFG0, 0x08);			/* CDIRQ disabled/masked, Pattern Generator disabled,	PWM disabled,PWM off-state is low */
	lm8330_write(lm, 2, LM8330_CMD_SET_TIMIC, 0x3F);			/* This register clears timer and pattern interrupts */
	lm8330_write(lm, 2, LM8330_CMD_SET_PWMWP, 0);				/* set PWM SCRIPT pointer buffer */
#ifdef SCRIPT_1
	// This script outputs a square wave with a duty cycle at 25%.  Why???????????????????????????????
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x40, 0x00);		//0x40FF set duty cycle to 00%
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x01, 0x7F);		//ramp 1 inc 126
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x01, 0x7F);		//ramp 1 inc 126
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x01, 0xFF);		//ramp 1 dec 126
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x01, 0xFF);		//ramp 1 dec 126
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x00, 0x00);		//goto start script
#endif
#ifdef SCRIPT_2
//This script outputs a square wave with a duty cycle that varies continuously from 0% to 25% (a minute or two) then outputs a square wave with a duty cycl 50%. Why??????????????????????????
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x40, 0x7F);		//set duty cycle to 50%
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0xBF, 0xC1);		//loop
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x40, 0x00);		//set duty cycle to 0%
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0xBF, 0xC1);		//loop
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x40, 0xFF);		//set duty cycle to 100%
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0xBF, 0xC1);		//loop
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x00, 0x00);		//go to start script
#endif
#ifdef SCRIPT_3
//This script outputs a square wave with a duty cycle that varies continuously from 0% to 25% (a minute or two), then stop. Why??????????????????????????
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x40, 0x7F);		//set duty cycle to 50%
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0xBF, 0xC1);		//loop
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x40, 0x00);		//set duty cycle to 0%
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0xBF, 0xC1);		//loop
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x40, 0xFF);		//set duty cycle to 100%
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0xBF, 0xC1);		//loop
	lm8330_write(lm, 3, LM8330_CMD_SET_PWMCFG, 0x00, 0x00);		//go to start
#endif	
	
	/* Command repeated because some keypad configuration instruction puts it in sleep mode. ??????????????  */
	lm8330_write(lm, 2, LM8330_CMD_CLKMODE, 0x01); 				/*set Operation mode */

	lm8330_write(lm, 2, LM8330_CMD_SET_PWMCFG0, 0x06);			/* Start pwm script

	/*
	 * Not much we can do about errors at this point, so just hope
	 * for the best.
	 */

	return 0;
}

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    如第47页所示,0x7E是低字节,0x7F是高字节,因此必须先编写LSB。

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    在我多次尝试中,我还尝试编写LSB,然后编写MSB,但仍然不起作用。 然后,我注意到,如果在KBDDEDCFG寄存器中首先写入MSB,然后写入LSB,则键盘工作正常,这与数据表第46页上的报告不同。

    更新

    我已重新尝试正确写入以注册0xFE,现在它似乎可以正常工作。 也许当我做各种测试的时候,也有一些其他的问题。 我将进行其他测试以确认问题的解决。
    谢谢。

    最后一个问题。
    使用以下简单脚本

    lm8330_write(Lm,3,LM8330_CMD_SET_PWMCFG,DUTYCYCLE,0x40);
    DUTYCYCLE = 0,...,255

    我已经用不同的工作周期和125Hz频率执行了各种测试。

    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0x00,0x40);//将占空比设置为0 %


    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0x40,0x40);//将占空比设置为25 %


    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0x7E,0x40);//将占空比设置为49,9 %
    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0x7F,0x40);// PWM输出= 0
    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0x80,0x40);// PWM输出= 0
    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0x81,0x40);//将占空比设置为50,1 %


    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0xC0,0x40);//将占空比设置为75 %


    lm8330_write(lm,3,LM8330_CMD_SET_PWMCFG,0xFF,0x40);//将占空比设置为100 %


    是否可以设定更高的频率或125Hz为最大可能频率?
    为什么根据所示的测试,值0x7F和0x80不可用?

  • 请注意,本文内容源自机器翻译,可能存在语法或其它翻译错误,仅供参考。如需获取准确内容,请参阅链接中的英语原文或自行翻译。

    谢谢克莱门斯。

    您好,Luigi,

    很高兴听到您能够解决您的问题。 如果您遇到任何其他问题,请告知我们。

    -Bobby