Lua:调用自己模块中的函数

我创建了一个用于 RTC 的模块,它看起来像这样:

local moduleName = ...
local M = {}
_G[moduleName] = M

---------- 本地变量 ---------------------
local id = 0
local address = 0x68

---------- 辅助函数 --------------------
local function bcdToDec(val)
    local hl=bit.rshift(val, 4)
    local hh=bit.band(val,0xf)
    local hr = string.format("%d%d", hl, hh)
  return string.format("%d%d", hl, hh)
end

local function decToBcd(val)
   local d = string.format("%d",tonumber(val / 10))
   local d1 = tonumber(d*10)
   local d2 = val - d1
   return tonumber(d*16+d2)
end

---------- 模块函数 --------------------
function M.Init(sda, scl)
    i2c.setup(id, sda, scl, i2c.SLOW)
end

function M.PrintTime()
    i2c.start(id)
    i2c.address(id, address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, address, i2c.RECEIVER)
    c=i2c.read(id, 7)
    i2c.stop(id)
    s = bcdToDec(string.byte(c,1))
    m = bcdToDec(string.byte(c,2))
    h = bcdToDec(string.byte(c,3))

    time=string.format(" %s:%s:%s", h, m, s)
    print(time);
end

function M.PrintDate()
    i2c.start(id)
    i2c.address(id, address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id, address, i2c.RECEIVER)
    c=i2c.read(id, 7)
    i2c.stop(id)
    s = bcdToDec(string.byte(c,1))
    m = bcdToDec(string.byte(c,2))
    h = bcdToDec(string.byte(c,3))
    wkd = bcdToDec(string.byte(c,4))
    day = bcdToDec(string.byte(c,5))
    month = bcdToDec(string.byte(c,6))
    year = bcdToDec(string.byte(c,7))

    time=string.format(" %s.%s.%s", day, month, year)
    print(time);
end

return M

我将该文件保存为 "ds3231_m.lua"。从另一个文件中调用函数的方法如下:

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
m.PrintTime()
--m.PrintDate()
package.loaded.ds3231_m = nil

以及

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
--m.PrintTime()
m.PrintDate()
package.loaded.ds3231_m = nil

但是当我尝试同时调用两个函数时:

m = require 'ds3231_m'
m.Init(2,1)   --sda, scl = 2, 1
m.PrintTime()
m.PrintDate()
package.loaded.ds3231_m = nil

我会得到一个错误:

test.lua:4: attempt to call field 'PrintDate' (a nil value)

有人能告诉我出了什么问题吗?

非常感谢您!

敬礼

点赞
用户5352026
用户5352026

PrintTime(和PrintDate)中,您正在执行m = something。这会覆盖m = require(...)中的_m_。您应该在这些功能中使用本地变量:

function M.PrintTime()
    i2c.start(id)
    i2c.address(id,address, i2c.TRANSMITTER)
    i2c.write(id, 0x00)
    i2c.stop(id)
    i2c.start(id)
    i2c.address(id,address, i2c.RECEIVER)
    local c=i2c.read(id, 7)
    i2c.stop(id)
    local s = bcdToDec(string.byte(c,1))
    local m = bcdToDec(string.byte(c,2))
    local h = bcdToDec(string.byte(c,3))

    local time=string.format(" %s:%s:%s", h, m, s)
    print(time);
end

这样,您就不会编辑任何全局变量。对于PrintDate也要做同样的事情。

(如果您使用other_name_than_m = require(...)那么您不会注意到,但是print(m)仍然会打印一个数字,即从something开始的分钟数)

2016-02-16 17:14:30